天天看點

Java Review (二十、基礎類庫----常用類:Object、String、StringBuffer、StringBuilder、Math)Object 類String 、 StringBuffer 和 StringBuilder 類Math 類

文章目錄

Object 類是所有類、數組、枚舉類的父類 ,也就是說, Java 允許把任何類型的對象賦給 Object 類型的變量 。 當定義一個類時沒有使用 extends 關鍵字為它顯式指定父類,則該類預設繼承 Object 父類。

因為所有的 Java 類都是 Object 類的子類 , 是以任何 Java 對象都可以調用 Object 類的方法 。 Object類提供了如下幾個常用方法 :

  • boolean equals(Object obj): 判斷指定對象與該對象是否相等 。 此處相等的标準是 , 兩個對象是同一個對象,是以該 equalsO方法通常沒有太大的實用價值 。
  • protected void fmalize(): 當系統中沒有引用變量引用到該對象時,垃圾回收器調用 此方法來清理該對象的資源 。
  • Class<?> getClass(): 傳回該對象的運作時類。
  • int hashCode(): 傳回該對象的 hashCode 值。在預設情況下, Object 類的 hashCode()方法根據該對象的位址來計算 但很多類都 重寫了 Object 類的 hashCode()方法,不再根據位址來計算其 hashCode()方法值 。
  • String toString(): 傳回 該對象 的 字元串表示 , 當程式用System.out.println()方法輸出一個對象,或者把某個對象和字元串進行連接配接運算時,系統會自動調用該對象的 toString()方法傳回該對象的字元串表示 。 Object 類的 toString()方法傳回"運作時類名@十六進制 hashCode 值"格式的字元串 ,但很多類都重寫了 Object 類 的 toString()方法,用于傳回可以表述該對象資訊的字元串。

除此之外 , Object 類還提供了 wai() 、 notify() 、 notifyAll()幾個方法,通過這幾個方法可以控制線程的暫停和運作。

Java 還提供了一個 protected 修飾的 clone()方法 , 該方法用于幫助其他對 象來實作"自我克隆",所謂"自我克隆"就是得到一個目前對象的副本,而且二者之間完全隔離。由于 Object 類提供的 clone()方法使用了 protected 修飾,是以該方法隻能被子類重寫或調用。

CloneTest.java

class Address {
    String detail;

    public Address(String detai1) {
        this.detail = detai1;
    }
}

// 實作 C1oneab1e 接口
class User implements Cloneable {
    int age;
    Address address;

    public User(int age) {
        this.age = age;
        address = new Address("廣州天河 ");
    }

    // 通過調用 super.c1one ()來實作 c1one ()方法
    public User clone() throws CloneNotSupportedException {
        return (User) super.clone();
    }

}

public class CloneTest {
    public static void main(String[] args) throws CloneNotSupportedException {
        User u1 = new User(29);
        // clone 得到 u1對象的副本
        User u2 = u1.clone();
        // 判斷 u1 、 u2 是否相同
        System.out.println(u1 == u2); // ①
        // 判斷 u1 、 u2 的 address 是否相同
        System.out.println(u1.address == u2.address); // ②
    }

}      

Object 類提供的 Clone機制隻對對象裡各執行個體變量進行"簡單複制",如果執行個體變量的類型是引用類型, Object 的 Clone 機制也隻是簡單地複制這個引用變量,這樣原有對象的引用類型的執行個體變量與克隆對象的引用類型的執行個體變量依然指向記憶體中的同一個執行個體,是以上面程式在②号代碼處輸出 true。上面程式"克隆 "出來的u1、u2 所指向的對 象在記憶體中的存儲示意圖如圖所示 。

Object 類提供的克隆機制

Java Review (二十、基礎類庫----常用類:Object、String、StringBuffer、StringBuilder、Math)Object 類String 、 StringBuffer 和 StringBuilder 類Math 類
API: java.lang.Object

字元串就是一連串的字元序 列, Java 提供 了 String 、 StringBuffer 和 StringBuilder 三個類來封裝宇符串,并提供了 一系列方法來操作字元串對象 。

  • String 類是不可變類 ,即 一旦一個 String 對象被建立以後,包含在這個對象中的字元序列是不可改變的 , 直至這個對象被銷毀。
  • StringBuffer 對 象 則代 表一個字元序列可變的 字元串 ,當 一個 StringBuffer 被建立以後,通過StringBuffer 提供的 append() 、 insert() 、 reverse() 、 setCharAt() 、 setLength()等方法可以改變這個字元串對象的宇符序列。一旦通過 StringBuffer 生成了 最終想要的字元串,就可以調用它的 toStringO方法将其轉換為一個 String 對象 。
  • StringBuilder 類是 JDK 1.5 新增的類 ,它也代表可變宇符串對象 。 實際上, StringBuilder 和 StringBuffer基本相似,兩個類的構造器和方法也基本相同。不同的是 , StringBuffer 是線程安全的,而 StringBuilder則沒有實作線程安全功能 ,是以性能略高。是以在通常情況下,如果需要建立一個内容可變的字元串對象, 則應該優先考慮使用 StringBuilder 類。

String類提供了大量構造器來建立String對象,其中如下幾個有特殊用途:

  • String():建立一個包含0個字元串序列的String對象(并不是傳回null)。
  • String(byte[] bytes, Charset charset):使用指定的字元集将指定的byte[擻組解碼成一個新的String 對象。
  • String(byte[] bytes, int offset, int length):使用平台的預設字元集将指定byte[]數組從ofifeet開始、長度為length的子數組解碼成一個新的String對象。
  • String(byte[] bytes, int offset, int length, String charsetName):使用指定的字元集将指定的 byte[]數 組從offset開始、長度為length的子數組解碼成一個新的String對象。
  • String(byte[] bytes, String charsetName):使用指定的字元集将指定的byte[]數組解碼成一個新的 String 對象。
  • String(char[] value, int offset, int count):将指定的字元數組從offset開始、長度為count的字元元 素連綴成字元串。
  • String(String original):根據字元串直接量來建立一個String對象。也就是說,新建立的String 對象是該參數字元串的副本。
  • String(StringBuffer buffer):根據 StringBuffer 對象來建立對應的 String 對象。
  • String(StringBuilder builder):根據 StringBuilder 對象來建立對應的 String 對象。

String 類也提供了大量方法來操作字元串對象:

  • char charAt(int index): 擷取字元串中指定位置的字元。其中 , 參數 index 指 的是字元串的序數,字元串的序數從 0 開始到 length()-l 。 如下代碼所示:
String s = new String("fkit.org");
System .out. println("s.charAt(5): "+ s.charAt(5) );      

結果為:

s . charAt(5) : 0      
  • int compareTo(String anotherString): 比較兩個宇符串的大小 。 如果兩個字元串的字元序列相等,則傳回 0; 不相等時,從兩個字元串第 0 個字元開始比較,傳回第一個不相等的字元差。另一種情況,較長字元串的前面部分恰巧是較短的字元串,則傳回它們的長度差。
String s1 = new String( "abcdefghijklmn");
String s2 = new String( "abcdefghij ");
String s3 = new String( "abcdefghijalmn") ;
System.out .println( "sl. compareTo(s2) : " + sl. compareTo(s2) ) ; //傳回長度差
System.out.println( "sl. compareTo (s3): " + sl. compareTo(s3) ) ; //傳回 'k'-'a' 的差      

結果為 :

s1.compareTo(s2): 4
s1.compareTo(s3) : 10      
  • String concat(String s):将該 String 對象與調用對象連接配接在一起。與 Java 提供的字元串連接配接運算符" +"的功能相同。
  • boolean contentEquals(StringBuffer sb): 将該 String 對象與 StringBuffer 對象 sb 進行比較,當它們包含的字元序列相同時傳回 true 。
  • static String copyValueOf(char[] data): 将字元數組連綴成字元串,與 String(char[] content)構造器的功能相同 。
  • static String copyValueOf(char[] data, int offset, int count): 将 char 數組的子數組中的元素連綴成字元串,與 String(char[] value, int offset, int count)構造器的功能相同 。
  • boolean endsWith(String suffix): 傳回該 String 對象是否以 suffix 結尾 。
String s1 = "fkit. org"; String s2 = ". org";
System.out .println("s1 .endsWith(s2): " + s1.endsWith(s2) );      
s1 .endsWith(s2): true      
  • boolean equals(Object anObject): 将該字元串與指定對象比較,如果二者包含的字元序列相等,則傳回 true; 否則傳回 false 。
  • boolean equalsIgnoreCase(String s):與前 一個方法基本相似,隻是忽略字元的大小寫 。
  • byte[] getBytes(): 将 該 String 對象轉換成 byte 數組 。
  • void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin): 該方法将字元串中從 srcBegin 開始,到 srcEnd 結束的字元複制到 dst 字元數組中,其中 dstBegin 為目标字元數組的起始複制位置。
char[] s1 = {'I' ,' ', ' l' , ' o' , ' v' , ' e ' ,' ', 'j' , ' a' , ' v ' , ' a'); // s1=1 love_java
String s2 = new String( "ejb");
s2 .getChars(0 , 3, s1 , 7); // s1=I love java
System.out . println ( s1 );      
I love java      
  • int indexOf(int ch): 找出 ch 字元在該字元串中第一次 出現的位置 。
  • int indexOf(int ch, int fromIndex): 找出 ch 字元在該字元串中從企fromIndex 開始後第一 次出現的位置。
  • int indexOf(String s):找出 str 子字元串在該宇符串中第 一次出現的位置 。
  • int indexOf(String s, int fromIndex): 找出 s位子字元串在該字元串中從 fromIndex 開始後第一次出現的位置。
String s = "www.fkit .org"; String ss = "it ";
System. out .print1n( "s.indexOf( ' r ' ): " + s .indexOf( ' r ') );
System .out.print1n( "s . indexOf( ' r ' , 2) : " + s.indexOf('r ' , 2) );
System.out.print1n( " s . indexOf(ss): " + s.indexOf(ss)) ;      
s .indexOf( 'r'): 10
s . indexOf (' r ' , 2) : 10
s . indexOf (ss) : 6      
  • int lastIndexOf(int ch): 找出 ch 字元在該字元串中最後一次出現的位置。
  • int lastIndexOf(int ch, int fromIndex): 找出 ch 字元在該字元串 中從 fromIndex 開始後最後一次出現的位置 。
  • int lastIndexOf(String str):找出 str子字元串在該字元串中最後 一次 出現的位置 。
  • int lastIndexOf(String str, int fromIndex): 找出 str 子字元串在該字元串中從 台fromlndex 開始後最後一次出現的位置 。
  • int length(): 傳回目前字元串長度。
  • String replace(char oldChar, char newChar): 将字元串中的第一個 oldChar 替換成 newChar 。
  • boolean startsWith(String prefix): 該 String 對象是否以 prefix 開始。
  • boolean startsWith(String prefix , int toffset): 該 String 對象從 toffset 位置算起,是否以 prefix 開始。
String s = "www . fki t .org"; String ss = "www"; String sss = "fkit ";
System.out .print1n("s.startsWith (ss): " + s.startsWith(ss) );
System.out .print1n( "s.startsWith(sss , 4): " + s.startsWith (sss , 4));      
s .startsWith(ss) : true
s.startsWith(sss , 4): true      
  • String substring(int beginlndex): 擷取從 beginlndex 位置開始到結束的子字元串。
  • String substring(int beginlndex, int endIndex): 擷取從 beginIndex 位置開始到 endlndex 位置的子字元串。
  • char[] toCharArray(): 将該 String 對象轉換成 char 數組。
  • String toLowerCase(): 将字元串轉換成小寫。
  • String toUpperCase(): 将字元串轉換成大寫。
String s = "fkjava.org ";
System.out.print1n( "s.toUpperCase() : " + s . toUpperCase()) ;
System.out.print1n( "s.toLowerCase(): " + s.toLowerCase()) ;      
s . toUpperCase() : FKJAVA .ORG
s.toLowerCase() : fkjava .org      
  • static String valueOf(X x): 一系列用于将基本類型值轉換為 String 對象的方法 。

String 類是不可變的, String類的執行個體一旦生成就不會再改變了。

例如如下代碼:

String str1 = "java";
str1 = str1 + "struts ";
str1 = str1 + " spring";      

上面程式除使用了 3 個字元串直接量之外,還會額外生成 2 個字元串直接量一一 "java"和 "struts"連接配接生成的 “javastruts” , 接着 "javastruts"與 "spring"連接配接生成 的 “javastrutsspring” , 程式中 的 strl 依次指向 3個不同的字元串對象。

字元串存儲

對于不同版本的JDK,String類在記憶體中有不同的優化方式。具體來說,早期JDK版本的String總是以char[]存儲,它的定義如下:

public final class String {
    private final char[] value;
    private final int offset;
    private final int count;
}      

而較新的JDK版本的String則以byte[]存儲:如果String僅包含ASCII字元,則每個byte存儲一個字元,否則,每兩個byte存儲一個字元,這樣做的目的是為了節省記憶體,因為大量的長度較短的String通常僅包含ASCII字元:

public final class String {
    private final byte[] value;
    private final byte coder; // 0 = LATIN1, 1 = UTF16
}      
java.lang.String

為了能高效拼接字元串,Java标準庫提供了StringBuilder,它是一個可變對象,可以預配置設定緩沖區,這樣,往StringBuilder中新增字元時,不會建立新的臨時對象:

StringBuilder sb = new StringBuilder(1024);
for (int i = 0; i < 1000; i++) {
    sb.append(',');
    sb.append(i);
}
String s = sb.toString();      

StringBuilder 提供了一系列插入、追加、改變該字元串裡包含 的 字元序 列的方法 。 而 StringBuffer與其用法完全相同,隻是 StringBuffer 是線程安全 的 。

StringBuilder 、 StringBuffer 有兩個屬性 : length 和 capacity , 其中 length 屬性表示其包含的字元序列的長度。與 String 對象的 length 不同的 是:StringBuilder、 StringBuffer 的 length 是可以改變的,可以通過 length()、 setLength(int len)方法來訪 問和修改其字元序列的長度。 capacity 屬性表示 StringBuilder的容量, capacity 通常比 length 大,程式通常無須關心 capacity 屬性。 如下程式示範了 StringBuilder 類的用法:

StringBuilderTest.java

public class StringBuilderTest {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder(); 
        // 追加字元串 
        sb.append("java");//sb = "java" 
        // 插入 
        sb.insert(0 , "hello "); // sb="hello java" 
        // 替換 
        sb.replace(5, 6, ","); // sb="hello,java" 
        System.out.println(sb); 
        // 删除 
        sb.delete(5, 6); // sb="hellojava" 
        System.out.println(sb); 
        // 反轉 
        sb.reverse(); // sb="avajolleh" 
        System.out.println(sb); 
        System.out.println(sb.length()); // 輸出9 
        System.out.println(sb.capacity()); // 輸出16 
        // 改變StringBuilder的長度,将隻保留前面部分 
        sb.setLength(5); // sb="avajo" 
        System.out.println(sb); 
      
    }
}      
java.lang.StringBuilder java.lang.StringBuffer

Java 提供了基本的+、一、 *、 /、%等基本算術運算的運算符,但對于更複雜的數學運算 ,例如,三角函數、對數運算、指數運算等則無能為力 。 Java 提供了 Math 工具類來完成這些複雜的運算, Math類是一個工具類,它的構造器被定義成 private 的, 是以無法建立 Math 類的對象 ; Math 類中的所有方法都是類方法,可以直接通過類名來調用它 們 。 Math 類除提供 了大量靜态方法之外,還提供了兩個類變量 : PI 和 E , 正如它們名 字所暗示的,它們的值分别等于π平日 e 。

下面程式示範了 Math 類 的用法 。

MathTes.java

public class MathTest {
    public static void main(String[] args) {
        /* ------下面是三角運算-------- */
        // 将弧度轉換成角度
        System.out.println(" Math.toDegrees(1.57): " + Math.toDegrees(1.57));
        // 将角 度轉換為弧度
        System.out.println(" Math.toRadians (90): " + Math.toRadians(90));
        // 計算反餘弦,傳回的角度範圍在 0 . 0 到 pi 之間
        System.out.println(" Math . acos(1 . 2): " + Math.acos(1.2));
        // 計算反正弦,傳回的角度範圍在 -p工 /2 到 pi/2 之間
        System.out.println(" Math.as 工 n(0.8 ): " + Math.asin(0.8));
        // 計算反正切,傳回的角度範圍在 -pi/2 到 pi /2 之間
        System.out.println("Math . atan(2.3): " + Math.atan(2.3));
        // 計算三角餘弦
        System.out.println("Math . cos(1 . 57): " + Math.cos(1.57));
        // 計算雙 曲餘弦
        System.out.println(" Math . cosh(1 . 2 ): " + Math.cosh(1.2));
        // 計算正弦
        System.out.println(" Math.sin(1.57 ): " + Math.sin(1.57));
        // 計算雙曲正弦
        System.out.println(" Math . sinh(1 . 2 ): " + Math.sinh(1.2));
        // 計算三角正切
        System.out.println("Math . tan(0 . 8 ): " + Math.tan(0.8));
        // 計算雙曲正切
        System.out.println("Math . tanh(2 . 1 ): " + Math.tanh(2.1));

        // 将矩形坐标 (x , y) 轉換成極坐标 (r , thet))
        System.out.println("Math . atan2(0.1 , 0 . 2): " + Math.atan2(0.1, 0.2));

        /* -----下面是取整運算 -------- */
        // 取整 ,傳回小于目标數的最大整數
        System.out.println("Math.floor( - 1 . 2 ): " + Math.floor(-1.2));
        // 取整 ,傳回大于目标數的最小整數
        System.out.println("Math.ceil(I.2) : " + Math.ceil(1.2));
        // 四舍五入取整
        System.out.println("Math . round(2.3 ) : " + Math.round(2.3));
        /*------下面是乘方、開方、指數運算-----*/
        // 計算平方根
        System.out.println("Math . sqrt(2.3 ): " + Math.sqrt(2.3));
        // 計算立方根
        System.out.println("Math . cbrt(9 ): " + Math.cbrt(9));
        // 傳回歐拉數 e 的 n 次幕
        System.out.println("Math .exp(2 ): " + Math.exp(2));
        // 傳回 sqrt(x2 +y2) ,沒有中間溢出或下溢
        System.out.println("Math.hypot (4 , 4 ): " + Math.hypot(4, 4));
        // 按照 IEEE 754 标準的規定,對兩個參數進行餘數運算
        System.out.println("Math . IEEEremainder(5 , 2): " + Math.IEEEremainder(5, 2));
        // 計算乘方
        System.out.println("Math .pow (3, 2 ): " + Math.pow(3, 2));
        // 計算自然對數
        System.out.println(" Math.log(12 ): " + Math.log(12));
        // 計算底數為 10 的對數
        System.out.println("Math . logl0 ( 9) : " + Math.log10(9));
        // 傳回參數與 1 之和的自然對數
        System.out.println("Math.loglp ( 9) : " + Math.log10(9));
        /*------下面是符号相關的運算 ----------*/
        // 計算絕對值
        System.out.println(" Math . abs(-4.5): " + Math.abs(-4.5));
        // 符号指派 ,傳回帶有第二個浮點數符号的第一個浮點參數
        System.out.println("Math . copySign(I.2 , -1 . 0) : " + Math.copySign(1.2, -1.0));
        // 符号 函數,如果參數為 0 ,則傳回 0: 如果參數大于 0
        // 則傳回1. 0 ; 如果參數小于 0 ,則傳回 - 1. 0
        System.out.println(" Math . sig口 um (2. 3): " + Math.signum(2.3));
        /*-----下面是大小相關的運算----- */
        // 找出最大值
        System.out.println("Math.max(2 . 3 , 4.5) : " + Math.max(2.3, 4.5));
        // 計算最小值
        System.out.println("Math . min(I . 2 , 3 . 4) : " + Math.min(1.2, 3.4));

        // 傳回第 一個參數和第二個參數之間與第一個參數相鄰的浮點數
        System.out.println("Math.nextAfter(l . 2 , 1.0) :" + Math.nextAfter(1.2, 1.0));
        // 傳回比目标數略大的浮點數
        System.out.println("Math . nextUp(l . 2 ): " + Math.nextUp(1.2));
        // 傳回 一個僞随機數,該值大于等于 0 . 0 且小于1. 0
        System.out.println("Math. randorn (): " + Math.random());
    }

}      
java.lang.Math

參考:

【1】:《瘋狂Java講義》

【2】:

https://www.liaoxuefeng.com/wiki/1252599548343744/1260469698963456