天天看點

JavaDay16-P104-P142—二分法查找—String類—常量池—包裝—裝箱、拆箱—NumberFormatException

1.二分法查找——建立在數組排序之上

案例程式:

class BinarySearch{
    public static void binarySearch(int[] arr,int des) {
        Arrays.sort(arr);/**對數組排序*/
        int begin=0;
        int end=arr.length;
        while (begin<=end){
            int mid=(begin+end)/2;
            if (des == arr[mid]){
                System.out.println("目标元素下标:"+mid);
                return;
            }
            else if (arr[mid]>des){ 	//目标數des在arr[mid]左邊
                end=mid-1;
            }
            else		//目标數des在arr[mid]右邊
                begin=mid+1;
        }
        System.out.println("本數組不含有目标數元素");
        return;
    }
}
           

2.String類

2.1.對String在記憶體存儲方面的了解:

  • 1.字元串一旦建立不可變。
  • 2.雙引号括起來的字元串存儲在字元串常量池中。(且相同字元串,位址固定)
    JavaDay16-P104-P142—二分法查找—String類—常量池—包裝—裝箱、拆箱—NumberFormatException
  • 3.字元串的比較必須使用equals方法。(不建議用“==”雙等号)
  • 4.String已經重寫了toString()和equals()方法。

面試題1:為何String一旦建立,不可改變?

我看過源代碼,String類中有byte[]數組,byte[]數組由final修飾。數組一旦建立,長度不可改變。并且被final修飾的引用一旦指向某個對象之後,不能再指向其他對象,是以String是不可變的。

面試題1.5:StringBuffer/StringBuilder為什麼是可變的?

我看過源代碼,StringBuffer/StringBuilder内部實際上是一個byte[]數組,這個數組沒有被final修飾,StringBuffer/StringBuilder的初始化容量我記得應該是16,當存滿之後會進行擴容,底層調用了數組copy方法System.arraycopy()……是這樣進行擴容的。是以StringBuffer/StringBuilder适合進行字元串的頻繁拼接。

面試題2:以下程式建立了幾個對象?

String s5=new String(“abc”);

String s6=new String(“abc”);

3個對象,方法區字元串常量池有1個“abc”,堆記憶體中有2個String對象。

2.2.String的構造方法

  • String s = “abc”;
  • String s = new String(“abc”);
  • String s = new String(byte數組);//數組中數字對應的字母傳入字元串s中。
  • String s = new String(byte數組, 起始下标, 長度);
  • String s = new String(char數組);
  • String s = new String(char數組, 起始下标, 長度);

2.3.String類常用的21個方法

2.3.1.compareTo不僅能比較大小,還能知道誰大誰小,傳回值為0,說明相等.

例如:abce與aBd比較時比到第二個就分出勝負了,後邊就不再比較了

  • System.out.print("compareTo不僅能比較大小,還能知道誰大誰小——");
      int result="abcd".compareTo("Ab");
      System.out.println(result);
               

2.3.2…contains()判斷前邊的字元串是否包含括号内的字元串

  • System.out.print("字元串1.contains(字元串2)判斷字元串1是否包含字元串2——");
       System.out.println("abcdef".contains("cde"));
               

2.3.3.字元串1.startsWith(字元串2)判斷字元串是否以…開頭

  • System.out.print("字元串1.startsWith(字元串2)判斷字元串1是否以字元串2開頭——");
      System.out.println("abcd".startsWith("a"));
               

2.3.4.判斷字元串是否以…結尾

  • System.out.print("字元串1.endsWith(字元串2)判斷字元串1是否以字元串2結尾——");
      System.out.println("abcd".endsWith("cd"));
               

2.3.5.判斷兩個字元串是否相等,而且忽略大小寫

  • System.out.print("字元串1.equalsIgnoreCase(字元串2)判斷兩個字元串是否相等,而且忽略大小寫——");
       System.out.println("ABc".equalsIgnoreCase("abc"));
               

2.3.6.判斷字元串是否為空

  • System.out.print("字元串..isEmpty()判斷字元串是否為空——");
      System.out.println("".isEmpty());
      System.out.println("1".isEmpty());
               

2.3.7.替換字元串中的某部分

  • System.out.print("字元串1.replace(字元串2,字元串3)字元串3替換掉字元串1中的字元串2部分——");
      String newstring="123456abc".replace("123456","opqwer");
      System.out.println("替換後的字元串:"+newstring);
               

2.3.8.以”-“号,把字元串拆分成數組

  • System.out.print("xxx-xx-xx-x.split(減号)以”-“号,把字元串拆分成數組——");
      String[] split="2020-09-01-20:20".split("-");
      for (int i=0;i< split.length;i++)
          System.out.print(split[i]+",");
      System.out.println();
               

2.4.StringBuffer/StringBuilder——可變長度字元串

  • 2.4.1.StringBuffer/StringBuilder初始化容量16 byte[]數組.
  • 2.4.2.StringBuffer/StringBuilder是完成字元串拼接操作的,方法名:append
  • 2.4.3.StringBuffer是線程安全的,因為它的所有方法都由synchronized(協調\同步)修飾,StringBuilder是非線程安全的。
  • 2.4.4.頻繁進行字元串拼接不建議使用“+”,因為會占用大量字元串常量池的記憶體。
  • StringBuffer.append()不會占用大量的字元串常量池記憶體。

案例程式輸出:123123China中國

  • System.out.print("StringBuffer初始化數組、.append()拼接數組——");
      StringBuffer sb=new StringBuffer(100);
      System.out.println("StringBuffer輸出:");
      sb.append(123);
      sb.append("123");
      sb.append("China");
      sb.append("中國");
      System.out.println(sb);/**輸出:123123China中國*/
               

面試題:如何優化StringBuffer性能?

在建立StringBuffer時,盡量給定一個初始化容量,盡可能減少底層數組的擴容次數。

為何字元串判斷是否相同,建議用".equal()",不建議用“==”?

eg.s1、s2中都是存的“方法區”中相同的字元串常量池的“位址”。

s3、s4,存的是堆記憶體中不同對象的位址。

s1 == s2?——>true;

s1 == s3?——>false;

s1 == s4?——>false;

s3 == s4?——>false;

s1.equal(s3)?—>true;

s1.equal(s4)?—>true;

s3.equal(s4)?—>true;

  1. String s1="abc";
               
  2. String s2="abc";
               
  3. String s3=new String("abc");
               
  4. String s4=new String("abc");
               

3.常量池的作用——Cache緩存機制——提升效率

java中-128~127的所有數字,都放在常量池中,不再new。

JVM會自動維護八種基本類型的常量池,int常量池中初始化-128~127的範圍,是以當為Integer i=127時,在自動裝箱過程中是取自常量池中的數值,而當Integer i=128時,128不在常量池範圍内,是以在自動裝箱過程中需new 128,是以位址不一樣。

//裝箱時,x、y存的都是整數常量池中的位址

Integer x=127;

Integer y=127;

x == y ?——>true

x.equals(y)?——>true(更換為引用資料類型的比較方法)

//超出-128~127範圍,a、b分别在不同位置new出了對象,存儲的位址不再相同。

Integer a=128;

Integer b=128;

a == b ?——>false

a.equals(b)?——>true(更換為引用資料類型的比較方法)

4.包裝

4.1.包裝有什麼用?

友善程式設計。

eg.下邊這個方法要代入Object型資料,不能傳入8種基本資料類型,此刻就需要包裝。

public void doSome(Object obj){

java語句;

……

}

4.2、8種包裝類的類名:

Byte、Short、Integer、Long、Float、Double、Boolean、Character

引用資料類型:

  • 1.類Class【String類、Object類(所有類的父類)】
               
  • 2.接口interface
               
  • 3.數組
               

5.所有數字的父類Number

6.照葫蘆畫瓢:學習Integer,其它的模仿Integer。

JavaDay16-P104-P142—二分法查找—String類—常量池—包裝—裝箱、拆箱—NumberFormatException
0. /**靜态方法實作資料類型轉換***Integer——>int**/
    System.out.print("靜态方法parse實作資料類型轉換:");
    int retValue=Integer.parseInt("123");
    System.out.println(retValue);

 1.   /***String——>int**/
    int m=Integer.parseInt("123");
    System.out.println("String——>int:"+m);
    
 2. /***int——>String**/
    String s2=m+"";
    System.out.println("int——>String:"+s2);
    
 3. /***String——>Integer**/
    Integer k=Integer.valueOf("123");
    System.out.println("String——>Integer:"+k);
    
 4./***Integer——>String**/
    String s=String.valueOf(k);
    System.out.println("Integer——>String:"+s);

 5./***int——>Integer**/
    /***自動裝箱*/
    Integer x=100;
    System.out.println("int——>Integer:"+x);

 6./***Integer——>int**/
    /**自動拆箱*/
    int y=x;
    System.out.println("Integer——>int:"+y);
           

7.什麼是裝箱?什麼是拆箱?

裝箱:基本資料類型——>引用資料類型

eg.Integer x = 100;

拆箱:引用資料類型——>基本資料類型

int y = x;

注意:拆箱時,字元串必須全為數字!否則出現:NumberFormatException(數字格式化異常)錯誤。

eg.Integer i = new Integer(“1b34”);//NumberFormatException(數字格式化異常)