傳智播客 劉意_2015年Java基礎視頻-深入淺出精華版 筆記(day11~day17)(2016年2月28日17:39:18)


day11
1.Eclipse的基本使用
編譯:
自動編譯,在保存的那一刻(ctrl+s)幫你做好了(class文件出現在bin目錄下)

 

2.Hierarchy 顯示Java繼承層次結構,選中類后F4

3.eclipse行號的顯示與隱藏

4.D:字體大小及顏色
        a:Java代碼區域的字體大小和顏色:
            window -- Preferences -- General -- Appearance -- Colors And Fonts -- Java修改 -- Java Edit Text Font
        b:控制台
            window -- Preferences -- General -- Appearance -- Colors And Fonts -- Debug -- Console font
        c:其他文件(比如文本文件txt)
            window -- Preferences -- General -- Appearance -- Colors And Fonts -- Basic -- Text Font
 
 
 
以上筆記總結
 
3:Eclipse空間的基本配置    
    A:程序的編譯和運行的環境配置(一般不改)
        window -- Preferences -- Java
        編譯環境:Compiler    默認選中的就是最高版本。
        運行環境:Installed JREs    默認會找你安裝的那個JDK。建議配置了Java的環境變量。
        問題:
        低編譯,高運行。可以。
        高編譯,低運行。不可以。
            建議,編譯和運行的版本一致。
 
    B:如何去掉默認注釋?
        window -- Preferences -- Java -- Code Style -- Code Templates
        選擇你不想要的內容,通過右邊Edit編輯。
        注意:請只刪除注釋部分,不是注釋部分的不要刪除。
 
    C:行號的顯示和隱藏
        顯示:在代碼區域的最左邊的空白區域,右鍵 -- Show Line Numbers即可。
        隱藏:把上面的動作再做一次。
 
    D:字體大小及顏色
        a:Java代碼區域的字體大小和顏色:
            window -- Preferences -- General -- Appearance -- Colors And Fonts -- Java修改 -- Java Edit Text Font
        b:控制台
            window -- Preferences -- General -- Appearance -- Colors And Fonts -- Debug -- Console font
        c:其他文件
            window -- Preferences -- General -- Appearance -- Colors And Fonts -- Basic -- Text Font
 
    E:窗體給弄亂了,怎么辦?
        window -- Reset Perspective(eclipse3.7)
         window --Perspective---Reset Perspective(eclipse4.5)
 
    F:控制台找不到了,怎么辦?
        Window--Show View—Console
 
eclipse快捷鍵
4.alt+/

 

5.
 
  * 常用快捷鍵
 * 1:格式化  ctrl+shift+f
 * 2:導入包  ctrl+shift+o
 *         如果該類僅僅在一個包中有,就自己顯示了
 *         如果該類在多個包中有,會彈出一個框框供你選擇
 * 3:注釋  
 *         單行:注釋 ctrl+/,取消注釋再來一次。
 *         多行:ctrl+shift+/,ctrl+shift+\
 * 4:代碼上下移動 
 *         選中代碼alt+上/下箭頭
 * 5:查看源碼
 *         選中類名(F3或者Ctrl+鼠標點擊)
 
導包
查看源碼
6.自動生成構造方法
    a:無參構造方法 在代碼區域右鍵--source--Generate Constructors from Superclass
    b:帶參構造方法 在代碼區域右鍵--source--Generate Constructors using fields.. -- finish
 
自動生成get/set方法
    在代碼區域右鍵--source--Generate Getters and Setters...
對應的快捷鍵方法
如下圖
 
即:Alt+Shift+S+c  :Generate  Constructors from Superclass
    Alt+Shift+S+o  :Generate C onstructors using Fields
     Alt+Shift+S+r  :Gene rate Getters and Setters
 

7.繼承抽象類,或者實現接口

  a:以前做法 先寫類,然后在類中在去繼承類或者實現接口

  b:現在做法 在創建類的時候,選擇要繼承的類或者實現的接口。

  Object是所有類的父類,所有類都直接或者間接的繼承自Object。

 

看到Override說說這是什么,有什么用。(起注解的作用)

8.eclipse制作幫助文檔
編寫源程序(設計接口,抽象類,具體類案例)
針對源程序添加文檔注釋
選中項目--右鍵--Export--Java--Javadoc—Finish
 
9.jar包
jar是什么?
jar是多個class文件的壓縮包。
jar有什么用?
用別人寫好的東西
打jar包
選中項目--右鍵--Export--Java--Jar--自己指定一個路徑和一個名稱--Finish
使用jar包
復制到項目路徑下(ctrl+c  ctrl+v)並添加至構建路徑。(右鍵-Build Path)
 
//
jar包有什么用,怎么用?
a:用於把別人寫好的東西,直接拿過來使用。
 
b:怎么用
(1)找到jar包。
(2)復制jar包,粘貼到要使用的項目路徑下。
(3)把jar添加到構建路徑。classpath。
選中jar包,右鍵Build path -- add to build path
(4)按照正常用法用就可以了。
 
在開發的時候,很多常見的功能,別人都會做好了,我們只需要導入別人的jar包即可。
比如說,上傳文件,下載文件,數據分頁等功能。
 
10.幾個小問題
如何查看項目所在路徑
選中 -- 右鍵 -- Properties -- Resource -- Location
導入項目要注意的問題
項目區域中不可能出現同名的項目(新建或者導入)
自己隨意建立的文件夾是不能作為項目導入的
修改項目問題
不要隨意修改項目名稱
如果真要修改,不要忘記了配置文件.project中的
<name>把這里改為你改后的名稱</name>
 
11.eclipse中代碼的高級(Debug)調試
    作用:
        調試程序
        查看程序執行流程
 
    如何查看程序執行流程
        要想看程序流程,就必須設置斷點。
 
        什么是斷點:
            就是一個標記,從哪里開始。
 
        如何設置斷點:
            你想看哪里的程序,你就在那個 有效程序的左邊雙擊即可。
 
        在哪里設置斷點:
            哪里不會點哪里。
            目前:我們就在每個方法的第一條有效語句上都加。
 
         如何運行設置斷點后的程序:
            右鍵 -- Debug as -- Java Application
 
        看哪些地方:
            Debug:斷點測試的地方
                在這個地方, 記住F6,或者點擊也可以。一次看一行的執行過程。
          Variables:查看程序的變量變化
            ForDemo:被查看的源文件
            Console:控制台
 
        如何去斷點:
            a:再次雙擊即可
            b:找到Debug視圖,Variables界面,找到Breakpoints,並點擊,然后看到所有的斷點,最后點擊那個雙叉。

個人補充:
     eclipse寫注釋方法:/* + 敲回車鍵(enter)
    eclipse寫文檔注釋方法:/** + 敲回車鍵(enter)
 
 
12.Object類
Object:類 Object 是類層次結構的根類。每個類都使用 Object 作為超類。
 * 每個類都直接或者間接的繼承自Object類。
 * 
 * Object類的方法:
 *         public int hashCode():返回該對象的哈希碼值。
 *             注意:哈希值是根據哈希算法計算出來的一個值,這個值和地址值有關,但是不是實際地址值。
 *                        你可以理解為地址值。
 * 
13Object類的Class
.public final Class getClass():返回此 Object 的運行時類
 *            Class類的方法:
 *                public String getName(): 以 String 的形式返回此 Class 對象所表示的實體
 
用法
 
        Student s = new Student();
 
        Class c = s.getClass();
        String str = c.getName();
        System.out.println(str);
 
        / /鏈式編程
        String str2 =  s.getClass().getName();
        System.out.println(str2);
 
輸出:
cn.itcast_01.Student
cn.itcast_01.Student
 
14.Object類的toString
public String toString():返回該對象的字符串表示。
 * 
 * Integer類下的一個靜態方法:
 *         public static String toHexString(int i):把一個整數轉成一個十六進制表示的字符串
 * 
 * 這個信息的組成就是這樣,但是這個信息是沒有任何意義的。所以,建議所有子類都重寫該方法。
 * 怎么重寫呢?
 *          把該類的所有成員變量值組成返回即可。
 *  重寫的最終版方案就是自動生成toString()方法。
 * 
 * 注意:
 *       直接輸出一個對象的名稱,其實就是調用該對象的toString()方法。

 

15.Object類的equals
String的equals()方法是重寫自Object類的, 比較的是字符串的內容是否相同
 
 
equals:
 *         引用類型:默認情況下,比較的是地址值。
 *         不過,我們可以根據情況自己重寫該方法。一般重寫都是自動生成,比較對象的成員變量值是否相同
 
16.Object類的clone
@Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
Cloneable:此類實現了 Cloneable 接口,以指示 Object.clone() 方法可以合法地對該類實例進行按字段復制。 
這個接口是 標記接口(無方法),告訴我們實現該接口的類就可以實現對象的復制了。
public class Student  implements Cloneable {
……
}
 
補充筆記
getClass()  返回對象的字節碼文件對象,反射中會詳細講解
兩個注意問題;
        A:直接輸出一個對象名稱,其實默認調用了該對象的toString()方法。
        B:面試題 
             ==和equals()的區別?
            A:==
                基本類型:比較的是值是否相同
                引用類型:比較的是地址值是否相同
            B:equals()
                只能比較引用類型。默認情況下,比較的是地址值是否相同。
                但是,我們可以根據自己的需要重寫該方法。
 
day12
1.Scanner
Scanner類:

一個可以使用正則表達式來解析基本類型和字符串的簡單文本掃描器。

常用的兩個方法:
 *         public int nextInt():獲取一個int類型的值
 *         public String nextLine():獲取一個String類型的值
 
// 先獲取一個int值,在獲取一個字符串
        // int a = sc. nextInt();
        // String s2 = sc. nextLine();
        // System.out.println("a:" + a + ",s2:" + s2);
        // System.out.println("-------------------");
如上的代碼所示,出現問題了:
 *         先獲取一個數值,在獲取一個字符串,會出現問題。
 *          主要原因:就是那個換行符號的問題。
 
如何解決呢?
 *        方案 A:先獲取一個數值后, 再創建一個新的鍵盤錄入對象獲取字符串
 *        方案 B:把所有的數據都先按照字符串獲取,然后要什么,你就對應的轉換為什么。(涉及字符串轉化為int)
        推薦方案B
方案A代碼如下
        int a =  sc.nextInt();
        Scanner  sc2 = new Scanner(System.in);
        String s =  sc2.nextLine();
        System.out.println("a:" + a + ",s:" + s);
2.String類(最常見,重要)
字符串:就是由多個字符組成的一串數據。也可以看成是一個字符數組。
 * 通過查看API,我們可以知道
 *         A:字符串字面值"abc"也可以看成是一個字符串對象。
 *         B:字符串是常量,一旦被賦值,就不能被改變。
3.String類的構造方法
 
 * 構造方法:
          public String():空構造
          public String(byte[] bytes):把字節數組轉成字符串
         public String(byte[] bytes,int index,int length):把字節數組的一部分轉成字符串
         public String(char[] value):把字符數組轉成字符串
         public String(char[] value,int index,int count):把字符數組的一部分轉成字符串
         public String(String original):把字符串常量值轉成字符串
 
  字符串的方法:
       public int length():返回此字符串的長度。
4.字符串是常量,一旦被賦值,就不能被改變。-----的理解
 
5.一個面試題
String s = new String(“hello”)和String s = “hello”;的區別?
有。前者會創建2個對象,后者創建1個對象。
背景知識:==:比較引用類型比較的是地址值是否相同
  equals:比較引用類型 默認也是比較地址值是否相同,而String類重寫了equals()方法,比較的是內容是否相同。
測試代碼
public static void main(String[] args) {
         String s1 = new String("hello");
        String s2 = "hello";
 
        System.out.println(s1 == s2);// false
        System.out.println(s1.equals(s2));// true
    }
內存圖解
注意字符串常量值
 
6.又一個面試題
看程序寫結果
public class StringDemo3 {
    public static void main(String[] args) {
        String s1 = new String("hello");
        String s2 = new String("hello");
        System.out.println(s1 == s2);//  false
        System.out.println(s1.equals(s2));//  true
 
        String s3 = new String("hello");
        String s4 = "hello";
        System.out.println(s3 == s4);//  false
        System.out.println(s3.equals(s4));//  true
 
        String s5 = "hello";
        String s6 = "hello";
        System.out.println(s5 == s6);//  true
        System.out.println(s5.equals(s6));//  true
    }
}
7.再一個面試題
看程序寫結果
public class StringDemo4 {
    public static void main(String[] args) {
        String s1 = "hello";
        String s2 = "world";
        String s3 = "helloworld";
         System.out.println(s3 == s1 + s2);// false
        System.out.println(s3.equals((s1 + s2)));// true
 
         System.out.println(s3 == "hello" + "world");// false 這個我們錯了,應該是true
        System.out.println(s3.equals("hello" + "world"));// true
 
        // 通過反編譯(xjad)看源碼,我們知道這里已經做好了處理。
         // System.out.println(s3 == "helloworld");
        // System.out.println(s3.equals("helloworld"));
    }
}
此題注意:
字符串如果是變量相加,先開空間,再拼接。
 字符串如果是常量相加,是先加,然后在常量池找,如果有就直接返回,否則,就創建。
 
8. String類的判斷功能:
 * boolean equals(Object obj):比較字符串的內容是否相同,區分大小寫
 * boolean equalsIgnoreCase(String str):比較字符串的內容是否相同,忽略大小寫
 * boolean contains(String str):判斷大字符串中是否包含小字符串
 * boolean startsWith(String str):判斷字符串是否以某個指定的字符串開頭
 * boolean endsWith(String str):判斷字符串是否以某個指定的字符串結尾
 * boolean isEmpty():判斷字符串是否為空。
 
字符串內容為空和字符串對象為空。
 *         String s = "";
 *         String s = null;
例子代碼
String s1 ="hello";
System.out.println("isEmpty:" + s1.isEmpty());// false
 
        String s4 = "";
        String s5 = null;
        System.out.println("isEmpty:" + s4.isEmpty());// true
        //  NullPointerException
        // s5對象都不存在,所以 不能調用方法,空指針異常
        System.out.println("isEmpty:" + s5.isEmpty());
 
9.String類的獲取功能
 * int length():獲取字符串的長度。
 * char charAt(int index):獲取指定索引位置的字符
 * int indexOf (int ch):返回指定字符在此字符串中第一次出現處的索引。
 *          為什么這里是int類型,而不是char類型?
 *          原因是:'a'和97其實都可以代表'a'
 * int indexOf(String str):返回指定字符串在此字符串中第一次出現處的索引。
 * int indexOf(int ch,int fromIndex):返回指定字符在此字符串中 從指定位置后第一次出現處的索引。
 * int indexOf(String str,int fromIndex):返回指定字符串在此字符串中從 指定位置后第一次出現處的索引。
 * String substring(int start):從指定位置開始截取字符串, 默認到末尾包含start這個索引
 * String substring(int start,int end):從指定位置開始到 指定位置結束截取字符串。 包括start索引但是不包end索引
10.字符串的遍歷
for (int x = 0; x < s.length(); x++) {
            // char ch = s.charAt(x);
            // System.out.println(ch);
            // 僅僅是輸出,我就直接輸出了
             System.out.println(s.charAt(x));
        }
11.實例分析
寫代碼前先寫需求思路
 
 1 需求:統計一個字符串中大寫字母字符,小寫字母字符,數字字符出現的次數。(不考慮其他字符)
 2  * 舉例:
 3  *         "Hello123World"
 4  * 結果:
 5  *         大寫字符:2個
 6  *         小寫字符:8個
 7  *         數字字符:3個
 8  * 
 9  * 分析:
10  *         前提:字符串要存在
11  *         A:定義三個統計變量
12  *             bigCount=0
13  *             smallCount=0
14  *             numberCount=0
15  *         B:遍歷字符串,得到每一個字符。
16  *             length()和charAt()結合
17  *         C:判斷該字符到底是屬於那種類型的
18  *             大:bigCount++
19  *             小:smallCount++
20  *             數字:numberCount++
21  * 
22  *             這道題目的難點就是如何判斷某個字符是大的,還是小的,還是數字的。
23  *             ASCII碼表:
24  *                 0    48
25  *                 A    65
26  *                 a    97
27  *             雖然,我們按照數字的這種比較是可以的,但是想多了,有比這還簡單的
28  *                 char ch = s.charAt(x);
29  * 
30  *                 if(ch>='0' && ch<='9') numberCount++
31  *                 if(ch>='a' && ch<='z') smallCount++
32  *                 if(ch>='A' && ch<='Z') bigCount++
33  *        D:輸出結果。
34  *
35  
36  */
37 public class StringTest2 {
38     public static void main(String[] args) {
39         //定義一個字符串
40         String s = "Hello123World";
41  
42         //定義三個統計變量
43         int bigCount = 0;
44         int smallCount = 0;
45         int numberCount = 0;
46  
47         //遍歷字符串,得到每一個字符。
48         for(int x=0; x<s.length(); x++){
49             char ch = s.charAt(x);
50  
51             //判斷該字符到底是屬於那種類型的
52             if(ch>='a' && ch<='z'){
53                 smallCount++;
54             }else if(ch>='A' && ch<='Z'){
55                 bigCount++;
56             }else if(ch>='0' && ch<='9'){
57                 numberCount++;
58             }
59         }
60  
61         //輸出結果。
62         System.out.println("大寫字母"+bigCount+"個");
63         System.out.println("小寫字母"+smallCount+"個");
64         System.out.println("數字"+numberCount+"個");
65     }
66 }

 

12.String的轉換功能:
  byte[] getBytes():把字符串轉換為字節數組。
  char[] toCharArray():把字符串轉換為字符數組。
   static String valueOf(char[] chs):把字符數組轉成字符串。
   static String valueOf(int i):把int類型的數據轉成字符串。
          注意: String類的valueOf方法可以把任意類型的數據轉成字符串。
 String toLowerCase():把字符串轉成小寫。
  String toUpperCase():把字符串轉成大寫。
  String concat(String str):把字符串拼接。
示例
String s = "JavaSE";
// byte[] getBytes():把字符串轉換為字節數組。
         byte[] bys = s.getBytes();
        for (int x = 0; x <  bys.length; x++) {
            System.out.println(bys[x]);
        }
        System.out.println("----------------");
 

        // char[] toCharArray():把字符串轉換為字符數組。
         char[] chs = s.toCharArray();
        for (int x = 0; x <  chs.length; x++) {
            System.out.println(chs[x]);
        }
        System.out.println("----------------");
 

        // static String valueOf(char[] chs):把字符數組轉成字符串。
         String ss = String.valueOf(chs);
        System.out.println(ss);
        System.out.println("----------------");
 
        // static String valueOf(int i):把int類型的數據轉成字符串。
        int  i = 100;
         String sss = String.valueOf(i);
        System.out.println(sss);
        System.out.println("----------------");
// String concat(String str):把字符串拼接。
        String s1 = "hello";
        String s2 = "world";
         String s3 = s1 + s2;//常用
        String s4 = s1.concat(s2);//不常用
        System.out.println("s3:"+s3);
        System.out.println("s4:"+s4);
13.一個案例
 
/*
 * 需求: 把一個字符串的首字母轉成大寫,其余為小寫。(只考慮英文大小寫字母字符)
 * 舉例:
 *         helloWORLD
 * 結果:
 *         Helloworld
 * 
 * 分析:
 *         A:先獲取第一個字符
 *         B:獲取除了第一個字符以外的字符
 *         C:把A轉成大寫
 *         D:把B轉成小寫
 *         E:C拼接D
 */
public class StringTest {
    public static void main(String[] args) {
        // 定義一個字符串
        String s = "helloWORLD";
 
        // 先獲取第一個 字符
        String s1 =  s.substring(0, 1);
        // 獲取除了第一個字符以外的 字符
        String s2 =  s.substring(1);
        // 把A轉成大寫
        String s3 = s1.toUpperCase();
        // 把B轉成小寫
        String s4 = s2.toLowerCase();
        // C拼接D
        String s5 = s3.concat(s4);
        System.out.println(s5);
 
        // 優化后的代碼
        / / 鏈式編程
        String result = s.substring(0, 1).toUpperCase()
                .concat(s.substring(1).toLowerCase());
        System.out.println(result);
    }
}
 
14.String類的其他功能:
  
 替換功能:
  String replace(char old,char new)
  String replace(String old,String new)
 
  去除字符串兩空格  (只可以去除前后的空格而不能去除中間的空格)
  String trim()
  
  按字典順序比較兩個字符串  
 int compareTo(String str)
 int compareToIgnoreCase(String str)
 
 
去除字符串兩空格  (只可以去除前后的空格而不能去除中間的空格)
  String trim()
 
// 去除字符串兩空格
        String s4 = " hello world  ";
        String s5 = s4.trim();
        System.out.println("s4:" + s4 + "---");
        System.out.println("s5:" + s5 + "---");
 
15.String類的compareTo方法的源碼解析
問題引入
String s1 =  "hello";
        String s2 =  "hel";
        System.out.println(s1.compareTo(s2)); // 輸出為 2
解決:看源碼(看compareTo)
hello與hel的字符串比較
 
解析:
  private final char value[];
 
     字符串會自動轉換為一個字符數組。
 
  public int compareTo(String anotherString) {
          //this -- s1 -- "hello"
          //anotherString -- s2 -- "hel"
 
        int len1 = value.length; //this.value.length--s1.toCharArray().length--5
        int len2 = anotherString.value.length;//s2.value.length -- s2.toCharArray().length--3
        int lim = Math.min(len1, len2); //Math.min(5,3); -- lim=3;
        char v1[] = value; //s1.toCharArray()
        char v2[] = anotherString.value;
 
        //char v1[] = {'h','e','l','l','o'};
        //char v2[] = {'h','e','l'};
 
        int k = 0;
        while (k < lim) {
            char c1 = v1[k]; //c1='h','e','l'
            char c2 = v2[k]; //c2='h','e','l'
            if (c1 != c2) {
                 return c1 - c2;
            }
            k++;
        }
         return len1 - len2; //5-3=2;
   }
 
   String s1 = "hello";
   String s2 = "hel";
   System.out.println(s1.compareTo(s2)); //  2
 
16 .字符串反轉
舉例:鍵盤錄入”abc”        
 * 輸出結果:”cba”
 * 
 * 分析:
 *         A:鍵盤錄入一個字符串
 *         B:定義一個新字符串
 *         C: 倒着遍歷字符串,得到每一個字符
 *             a:length()和charAt()結合
 *             b:把字符串轉成字符數組
 *         D:用新字符串把每一個字符拼接起來
 *         E:輸出新串
一種做法
===============================================
// 鍵盤錄入一個字符串
        Scanner sc = new Scanner(System.in);
        System.out.println("請輸入一個字符串:");
        String line = sc.nextLine();
 
        /*
        // 定義一個新字符串
        String result = "";
 
        // 把字符串轉成字符數組
        char[] chs = line.toCharArray();
 
        // 倒着遍歷字符串,得到每一個字符
        for (int x = chs.length - 1; x >= 0; x--) {
             // 用新字符串把每一個字符拼接起來
            result += chs[x];  (字符自動轉為字符串??)
        }
 
        // 輸出新串
        System.out.println("反轉后的結果是:" + result);
        */
=================================================
我的做法
System.out.println("請輸入一個字符串:");
        Scanner sc = new Scanner(System.in);
        String s = sc.nextLine();
 
        char[] ch = s.toCharArray();
        char temp;
 
        for (int x = 0; x < (ch.length) / 2; x++) {
            temp = ch[x];
            ch[x] = ch[ch.length - 1 - x];
            ch[ch.length - 1 - x] = temp;
        }
 
        String s2 = String.valueOf(ch);
        System.out.println(s2);
===================================================
17.day12筆記補充
Scanner
需要注意的小問題
        A:同一個Scanner對象,先獲取數值,再獲取字符串會出現一個小問題。
        B:解決方案:
            a:重新定義一個Scanner對象
            b:把所有的數據都用字符串獲取,然后再進行相應的轉換
 
day13
1.StringBuffer
線程安全(多線程講解)
 * 安全 -- 同步 -- 數據是安全的
 * 不安全 -- 不同步 -- 效率高一些
 * 安全和效率問題是永遠困擾我們的問題。
 * 安全:醫院的網站,銀行網站
 * 效率:新聞網站,論壇之類的
 * 
 * StringBuffer:
 *         線程安全的可變字符串。
 * 
 * StringBuffer和String的區別?
 *  前者長度和內容可變,后者不可變。
 * 如果使用前者做字符串的拼接,不會浪費太多的資源。
2
2.StringBuffer的構造方法:
 *         public StringBuffer():無參構造方法(最常用,相當於造了一個水杯而沒有裝水)
 *        public StringBuffer(int capacity):指定容量的字符串緩沖區對象
 *        public StringBuffer(String str):指定字符串內容的字符串緩沖區對象
 
 
StringBuffer sb = new StringBuffer();
        System.out.println("sb:" + sb);
        System.out.println("sb.capacity():" + sb.capacity());//16
        System.out.println("sb.length():" + sb.length());//0
 
3.StringBuffer的方法:
 *        public int capacity():返回當前容量。    理論值(水杯最多可以裝多少水)
 *        public int length():返回長度(字符數)。 實際值(實際上水杯有多少水)
4.StringBuffer的添加功能:
 * public StringBuffer append(String str):可以把任意類型數據添加到字符串緩沖區里面,並返回字符串緩沖區本身
 * 
 * public StringBuffer insert (int offset,String str):在 指定位置把任意類型的數據插入到字符串緩沖區里面,並返回字符串緩沖區本身
 
 

5.StringBuffer的刪除功能
 * public StringBuffer deleteCharAt(int index):刪除指定位置的字符,並返回本身
 * public StringBuffer delete(int start,int end):刪除從指定位置開始指定位置結束的內容,並返回本身(包括start不包括end)
 
        //  需求:我要刪除所有的數據
        sb.delete(0, sb.length());
 
6.StringBuffer的替換功能:
 * public StringBuffer replace(int start,int end,String str):從start開始到end用str替換
7.StringBuffer的反轉功能:(Stirng類沒有)
 * public StringBuffer reverse()
 
8.StringBuffer的截取功能: 注意返回值類型不再是StringBuffer本身了
 * public  String substring(int start)
 * public  String substring(int start,int end)
 
舉例:
// 創建字符串緩沖區對象
        StringBuffer sb = new StringBuffer();
 
        // 添加元素
        sb.append("hello").append("world").append("java");
        System.out.println("sb:" + sb);
 
        // 截取功能
        // public String substring(int start)
        String s = sb.substring(5);
        System.out.println("s:" + s);
        System.out.println("sb:" + sb);
 
        // public String substring(int start,int end)
        String ss = sb.substring(5, 10);
        System.out.println("ss:" + ss);
        System.out.println("sb:" + sb);
9 .StringBuffer和String的相互轉換
為什么我們要講解類之間的轉換:
 * A -- B的轉換
 * 我們把A轉換為B,其實是為了使用B的功能。
 * B -- A的轉換
 * 我們可能要的結果是A類型,所以還得轉回來。
 * 
 * String和StringBuffer的相互轉換?
 
 
===================================
public class StringBufferTest {
    public static void main(String[] args) {
        //  String -- StringBuffer
        //  方式1:通過構造方法(推薦)
        StringBuffer sb = new StringBuffer(s);
        //  方式2:通過append()方法
        StringBuffer sb2 = new StringBuffer();
        sb2.append(s);
        System.out.println("sb:" + sb);
        System.out.println("sb2:" + sb2);
        System.out.println("---------------");
 
        //  StringBuffer -- String
        StringBuffer  buffer = new StringBuffer("java");
        // String(StringBuffer buffer)
        //  方式1:通過構造方法
        String str = new String( buffer);
        //  方式2:通過toString()方法(推薦)
        String str2 = buffer.toString();
        System.out.println("str:" + str);
        System.out.println("str2:" + str2);
    }
}
====================================
10.把數組拼接成一個字符串(用String和StringBuffer實現)
推薦用StringBuffer,因為沒那么浪費空間
具體如下
public class StringBufferTest2 {
    public static void main(String[] args) {
        // 定義一個數組
         int[] arr = { 44, 33, 55, 11, 22 };
 
        // 定義功能
        // 方式1: 用String做拼接的方式
        String s1 = arrayToString(arr);
        System.out.println("s1:" + s1);
 
        // 方式2:用StringBuffer做拼接的方式
        String s2 = arrayToString2(arr);
        System.out.println("s2:" + s2);
    }
 
    // 用 StringBuffer做拼接的方式
    public static String arrayToString2(int[] arr) {
         StringBuffer sb = new StringBuffer();
 
         sb.append("[");
        for (int x = 0; x < arr.length; x++) {
            if (x == arr.length - 1) {
                 sb.append(arr[x]);
            } else {
                 sb.append(arr[x]).append(", ");
            }
        }
         sb.append("]");
 
        return  sb.toString();
    }
 
    // 用String做拼接的方式
    public static String arrayToString(int[] arr) {
         String s = "";
 
         s += "[";
        for (int x = 0; x < arr.length; x++) {
            if (x == arr.length - 1) {
                 s += arr[x];
            } else {
                 s += arr[x];
                s += ", ";
            }
        }
         s += "]";
 
        return  s;
    }
}
 
11.把字符串反轉(String和StringBuffer)
 
import java.util.Scanner;
 
public class StringBufferTest3 {
    public static void main(String[] args) {
        // 鍵盤錄入數據
        Scanner sc = new Scanner(System.in);
        System.out.println("請輸入數據:");
        String s = sc.nextLine();
 
        // 方式1: 用String做拼接
        String s1 = myReverse(s);
        System.out.println("s1:" + s1);
        // 方式2: 用StringBuffer的reverse()功能
        String s2 = myReverse2(s);
        System.out.println("s2:" + s2);
    }
 
    // 用StringBuffer的reverse()功能
    public static String myReverse2(String s) {
        // StringBuffer sb = new StringBuffer();
        // sb.append(s);
 
        // StringBuffer sb = new StringBuffer(s);
        // sb.reverse();
        //  return sb.toString();
 
        // 簡易版
        return new StringBuffer(s).reverse().toString();
    }
 
    // 用String做拼接
    public static String myReverse(String s) {
         String result = "";
 
        char[] chs = s .toCharArray();
        for (int x = chs.length - 1; x >= 0; x--) {
            // char ch = chs[x];
            // result += ch;
             result += chs[x];
        }
 
         return result;
    }
}
 
12.案例:判斷一個字符串是否是對稱字符串(String和StringBuffer實現)
例如"abc"不是對稱字符串,"aba"、"abba"、"aaa"、"mnanm"是對稱字符串
分析:
 *         判斷一個字符串是否是對稱的字符串,我只需要把
 *             第一個和最后一個比較
 *             第二個和倒數第二個比較
 *             ...
 *         比較的次數是長度除以2。
========================================
public class StringBufferTest4 {
    public static void main(String[] args) {
        // 創建鍵盤錄入對象
        Scanner sc = new Scanner(System.in);
        System.out.println("請輸入一個字符串:");
        String s = sc.nextLine();
 
        // 一個一個的比較
         boolean b = isSame(s);
        System.out.println("b:" + b);
 
        //用字符串緩沖區的反轉功能
        boolean b2 = isSame2(s);
        System.out.println("b2:"+b2);
    }
 
    public static boolean isSame2(String s) {
        return new StringBuffer(s).reverse().toString().equals(s);
    }
 
 
    // public static boolean isSame(String s) {
    // // 把字符串轉成字符數組
    // char[] chs = s.toCharArray();
    //
    //  for (int start = 0, end = chs.length - 1; start <= end; start++, end--) {
    //  if (chs[start] != chs[end]) {
    // return false;
    // }
    // }
    //
    // return true;
    // }
 
    public static boolean isSame(String s) {
         boolean flag = true;
 
        // 把字符串轉成字符數組
        char[] chs = s.toCharArray();
 
        for (int start = 0, end = chs.length - 1; start <= end; start++, end--) {
            if (chs[start] != chs[end]) {
                 flag = false;
                break;
            }
        }
 
         return flag;
    }
}
======================================================
13.類 StringBuilder(since  JDK1.5)

(API)一個可變的字符序列。此類提供一個與 StringBuffer兼容的 API,但不保證同步(效率較高,安全性低)。該類被設計用作 StringBuffer

 的一個簡易替換,用在字符串緩沖區被單個線程使用的時候(這種情況很普遍)。如果可能,建議優先采用該類,因為在大多數實現中,它比 StringBuffer 要快。

14.關於StringBuffer面試題

 

面試題:
 * 1: String,StringBuffer,StringBuilder的區別?
 * A: String內容不可變的,而 StringBuffer,StringBuilder都是 內容可變的。
 * B: StringBuffer同步的, 數據安全, 效率低; StringBuilder不同步的, 數據不安全, 效率高
 * 
 * 2: StringBuffer和數組的區別?
 * 二者都可以看出是一個容器,裝其他的數據。
 * 但是呢, StringBuffer的數據 最終是一個字符串數據
 * 而 數組可以放置多種數據,但 必須是同一種數據類型的。
 * 
 * 3:形式參數問題
 * String作為參數傳遞
 * StringBuffer作為參數傳遞 

 

 

 

形式參數:
 *         基本類型: 形式參數的改變不影響實際參數
 *         引用類型: 形式參數的改變直接影響實際參數
 * 
 * 注意:
 *          String作為參數傳遞,效果和基本類型作為參數傳遞是一樣的。

 

(要用debug查看一下)

 

public class StringBufferDemo {
    public static void main(String[] args) {
        String s1 = "hello";
        String s2 = "world";
        System.out.println(s1 + "---" + s2);//  hello---world
        change(s1, s2);
        System.out.println(s1 + "---" + s2);//  hello---world
 
        StringBuffer sb1 = new StringBuffer("hello");
        StringBuffer sb2 = new StringBuffer("world");
        System.out.println(sb1 + "---" + sb2);//  hello---world
        change(sb1, sb2);
        System.out.println(sb1 + "---" + sb2);//  hello---worldworld
 
    }
 
    public static void change(StringBuffer sb1, StringBuffer sb2) {
        sb1 = sb2;
        sb2.append(sb1);
    }
 
    public static void change(String s1, String s2) {
        s1 = s2;
        s2 = s1 + s2;
    }
}
 
debug過程截圖
 
 
 
 
 
 
 
 


 

字符串是一個特殊的引用類型,只能把它當作基本類型看  ,字符串例如"hello"看作常量
 
15.代碼摘錄:數組冒泡排序
===================================================
/*
 * 數組排序之冒泡排序:
 *         相鄰元素兩兩比較,大的往后放,第一次完畢,最大值出現在了最大索引處
 */
public class ArrayDemo {
    public static void main(String[] args) {
        // 定義一個數組
        int[] arr = { 24, 69, 80, 57, 13 };
        System.out.println("排序前:");
        printArray(arr);
 
        /*
        // 第一次比較
        // arr.length - 1是為了防止數據越界
        // arr.length - 1 - 0是為了減少比較的次數
        for (int x = 0; x < arr.length - 1 - 0; x++) {
            if (arr[x] > arr[x + 1]) {
                int temp = arr[x];
                arr[x] = arr[x + 1];
                arr[x + 1] = temp;
            }
        }
        System.out.println("第一次比較后:");
        printArray(arr);
 
        // 第二次比較
        // arr.length - 1是為了防止數據越界
        // arr.length - 1 - 1是為了減少比較的次數
        for (int x = 0; x < arr.length - 1 - 1; x++) {
            if (arr[x] > arr[x + 1]) {
                int temp = arr[x];
                arr[x] = arr[x + 1];
                arr[x + 1] = temp;
            }
        }
        System.out.println("第二次比較后:");
        printArray(arr);
 
        // 第三次比較
        // arr.length - 1是為了防止數據越界
        // arr.length - 1 - 2是為了減少比較的次數
        for (int x = 0; x < arr.length - 1 - 2; x++) {
            if (arr[x] > arr[x + 1]) {
                int temp = arr[x];
                arr[x] = arr[x + 1];
                arr[x + 1] = temp;
            }
        }
        System.out.println("第三次比較后:");
        printArray(arr);
 
        // 第四次比較
        // arr.length - 1是為了防止數據越界
        // arr.length - 1 - 3是為了減少比較的次數
        for (int x = 0; x < arr.length - 1 - 3; x++) {
            if (arr[x] > arr[x + 1]) {
                int temp = arr[x];
                arr[x] = arr[x + 1];
                arr[x + 1] = temp;
            }
        }
        System.out.println("第四次比較后:");
        printArray(arr);
        */
 
        // 既然聽懂了,那么上面的代碼就是排序代碼
        // 而上面的代碼重復度太高了,所以用循環改進
        // for (int y = 0; y < 4; y++) {
        // for (int x = 0; x < arr.length - 1 - y; x++) {
        // if (arr[x] > arr[x + 1]) {
        // int temp = arr[x];
        // arr[x] = arr[x + 1];
        // arr[x + 1] = temp;
        // }
        // }
        // }
 
        /*
        // 由於我們知道比較的次數是數組長度-1次,所以改進最終版程序
        for (int x = 0; x < arr.length - 1; x++) {
            for (int y = 0; y < arr.length - 1 - x; y++) {
                if (arr[y] > arr[y + 1]) {
                    int temp = arr[y];
                    arr[y] = arr[y + 1];
                    arr[y + 1] = temp;
                }
            }
        }
        System.out.println("排序后:");
        printArray(arr);
        */
 
        //由於我可能有多個數組要排序,所以我要寫成方法
         bubbleSort(arr);
         System.out.println("排序后:");
        printArray(arr);
    }
 
     //冒泡排序代碼
    public static void bubbleSort(int[] arr){
        for (int x = 0; x < arr.length - 1; x++) {
            for (int y = 0; y < arr.length - 1 - x; y++) {
                if (arr[y] > arr[y + 1]) {
                    int temp = arr[y];
                    arr[y] = arr[y + 1];
                    arr[y + 1] = temp;
                }
            }
        }
    }
 
     // 遍歷功能
    public static void printArray(int[] arr) {
        System.out.print("[");
        for (int x = 0; x < arr.length; x++) {
            if (x == arr.length - 1) {
                System.out.print(arr[x]);
            } else {
                System.out.print(arr[x] + ", ");
            }
        }
        System.out.println("]");
    }
}
============================================
數組高級冒泡排序原理圖解
 
經整理 后的代碼如下
public class BubbleTest {
    public static void  main(String[] args) {
        int[] arr = { 24, 69, 80, 57, 13 };
        System.out.println("排序前:");
        printArray(arr);
        bubbleSort(arr);
        System.out.println("排序后:");
        printArray(arr);
    }
 
    // 打印數組,遍歷功能
    public static void  printArray(int[] arr) {
        System.out.print("[");
        for (int x = 0; x < arr.length; x++) {
            if (x == arr.length - 1) {
                System.out. print(arr[x]);
            } else {
                System.out. print(arr[x] + ",");
            }
        }
 
        System.out. println("]");
    }
 
    public static void  bubbleSort(int[] arr) {
        for (int y = 0;  y < arr.length - 1; y++) {
            for (int x = 0; x <  arr.length - 1 - y; x++) {
                if (arr[x] > arr[x + 1]) {
                    int temp = arr[x];
                    arr[x] = arr[x + 1];
                    arr[x + 1] = temp;
                }
            }
        }
    }
 
}
 
16.代碼摘錄:數組選擇排序
數組排序之選擇排序:
 *         從0索引開始,依次和后面元素比較,小的往前放,第一次完畢, 最小值出現在了最小索引處
 
public class ArrayDemo {
    public static void main(String[] args) {
        // 定義一個數組
        int[] arr = { 24, 69, 80, 57, 13 };
        System.out.println("排序前:");
        printArray(arr);
 
        /*
        //  第一次
        int x = 0;
        for (int y = x + 1; y < arr.length; y++) {
            if (arr[y] < arr[x]) {
                int temp = arr[x];
                arr[x] = arr[y];
                arr[y] = temp;
            }
        }
        System.out.println("第一次比較后:");
        printArray(arr);
 
        //  第二次
        x = 1;
        for (int y = x + 1; y < arr.length; y++) {
            if (arr[y] < arr[x]) {
                int temp = arr[x];
                arr[x] = arr[y];
                arr[y] = temp;
            }
        }
        System.out.println("第二次比較后:");
        printArray(arr);
 
        //  第三次
        x = 2;
        for (int y = x + 1; y < arr.length; y++) {
            if (arr[y] < arr[x]) {
                int temp = arr[x];
                arr[x] = arr[y];
                arr[y] = temp;
            }
        }
        System.out.println("第三次比較后:");
        printArray(arr);
 
        //  第四次
        x = 3;
        for (int y = x + 1; y < arr.length; y++) {
            if (arr[y] < arr[x]) {
                int temp = arr[x];
                arr[x] = arr[y];
                arr[y] = temp;
            }
        }
        System.out.println("第四次比較后:");
        printArray(arr);
        */
 
         /*
        //通過觀察發現代碼的重復度太高,所以用循環改進
        for(int x=0; x<arr.length-1; x++){
            for(int y=x+1; y<arr.length; y++){
                if(arr[y] <arr[x]){
                    int temp = arr[x];
                    arr[x] = arr[y];
                     arr[y] = temp;
                }
            }
        }
        System.out.println("排序后:");
        printArray(arr);
        */
 
        //用方法改進
        selectSort(arr);
        System.out.println("排序后:");
        printArray(arr);
 
    }
 
    public static void selectSort(int[] arr){
        for(int x=0; x<arr.length-1; x++){
            for(int y=x+1; y<arr.length; y++){
                if(arr[y] <arr[x]){
                    int temp = arr[x];
                    arr[x] = arr[y];
                     arr[y] = temp;
                }
            }
        }
    }
 
    // 遍歷功能
    public static void printArray(int[] arr) {
        System.out.print("[");
        for (int x = 0; x < arr.length; x++) {
            if (x == arr.length - 1) {
                System.out.print(arr[x]);
            } else {
                System.out.print(arr[x] + ", ");
            }
        }
        System.out.println("]");
    }
}
17.二分查找
思路
 查找:
 *         基本查找:數組元素無序(從頭找到尾)
 *         二分查找(折半查找):數組元素有序
 * 
 * 分析:
 *         A:定義最大索引,最小索引
 *         B:計算出中間索引
 *         C:拿中間索引的值和要查找的值進行比較
 *             相等:就返回當前的中間索引
 *             不相等:
 *                 大    左邊找
 *                 小    右邊找
 *         D:重新計算出中間索引
 *             大    左邊找
 *                 max = mid - 1;
 *             小    右邊找
 *                 min = mid + 1;
 *         E:回到B
 */
public class ArrayDemo {
    public static void main(String[] args) {
        //定義一個數組
        int[] arr = {11,22,33,44,55,66,77};
 
        //寫功能實現
        int index = getIndex(arr, 33);
        System.out.println("index:"+index);
 
        //假如這個元素不存在后有什么現象呢?
        index = getIndex(arr, 333);
        System.out.println("index:"+index);
    }
 
    /*
     * 兩個明確:
     * 返回值類型:int
     * 參數列表:int[] arr,int value
     */
    public static int getIndex(int[] arr,int value){
        //定義最大索引,最小索引
        int max = arr.length -1;
        int min = 0;
 
        //計算出中間索引
        int mid = (max +min)/2;
 
        //拿中間索引的值和要查找的值進行比較
        while(arr[mid] != value){
            if(arr[mid]>value){
                max = mid - 1;
            }else if(arr[mid]<value){
                min = mid + 1;
            }
 
             //加入判斷
            if(min > max){
                return -1;
            }
 
            mid = (max +min)/2;
        }
 
        return mid;
    }
}
 
18.Arrays類  大多為靜態方法
Arrays:針對數組進行操作的工具類。比如說排序和查找。
 * 1:public  static String toString(int[] a) 把數組轉成字符串
 * 2:public  static void sort(int[] a) 對數組進行排序
 * 3:public  static int binarySearch(int[] a,int key) 二分查找
示例
=======================================
public class ArraysDemo {
    public static void main(String[] args) {
        // 定義一個數組
        int[] arr = { 24, 69, 80, 57, 13 };
 
        // public static String toString(int[] a) 把數組轉成字符串
        System.out.println("排序前:" + Arrays.toString(arr));
 
        // public static void sort(int[] a) 對數組進行排序
        Arrays.sort(arr);
        System.out.println("排序后:" + Arrays.toString(arr));
 
        // [13, 24, 57, 69, 80]
        // public static int binarySearch(int[] a,int key) 二分查找
        System.out.println("binarySearch:" + Arrays.binarySearch(arr, 57));
        System.out.println("binarySearch:" + Arrays.binarySearch(arr, 577));
    }
}
================================================
Arrays工具類的方法 源碼解析
public static String toString(int[] a)
public static void sort(int[] a) 底層是快速排序,知道就可以了。有空看,有問題再問我
public static int binarySearch(int[] a,int key)
 
開發原則:
     只要是對象,我們就要判斷該對象是否為null。
 
int[] arr = { 24, 69, 80, 57, 13 };
System.out.println("排序前:" + Arrays.toString(arr));
 
public static String toString(int[] a) {
    //a -- arr -- { 24, 69, 80, 57, 13 }
 
    if (a == null)
         return "null"; //說明數組對象不存在
    int iMax = a.length - 1; //iMax=4;
    if (iMax == -1)
         return "[]"; //說明數組存在,但是沒有元素。
 
     StringBuilder b = new StringBuilder();
    b.append('['); //"["
    for (int i = 0; ; i++) {
        b.append(a[i]); //"[24, 69, 80, 57, 13"
        if (i == iMax)
            //"[24, 69, 80, 57, 13]"
            return b.append(']').toString();
        b.append(", "); //"[24, 69, 80, 57, "
    }
}
-----------------------------------------------------
 
int[] arr = {13, 24, 57, 69, 80};
System.out.println("binarySearch:" + Arrays.binarySearch(arr, 577));
 
public static int binarySearch(int[] a, int key) {
    //a -- arr -- {13, 24, 57, 69, 80}
    //key -- 577
    return binarySearch0(a, 0, a.length, key);
}
 
private static int binarySearch0(int[] a, int fromIndex, int toIndex,
                                 int key) {
    //a -- arr --  {13, 24, 57, 69, 80}
    //fromIndex -- 0
    //toIndex -- 5
    // key -- 577(用一個不存在的數測試)                          
 
 
    int low = fromIndex; //low=0
    int high = toIndex - 1; //high=4
 
    while (low <= high) {
        int mid = (low + high)  >>> 1; //>>> 無符號右移,相當於除以2    mid=2,mid=3,mid=4
        int midVal = a[mid]; //midVal=57,midVal=69,midVal=80
 
        if (midVal < key)
            low = mid + 1; //low=3,low=4,low=5
        else if (midVal > key)
            high = mid - 1;
        else
            return mid; // key found
    }
     return -(low + 1);  // key not found.
}
19.基本類型包裝類概述
為了對基本數據類型進行更多的操作,更方便的操作,Java就針對每一種基本數據類型提供了對應的類類型。包裝類類型。
 * byte             Byte
 * short            Short
 * int                Integer
 * long                Long
 * float            Float
 * double            Double
 * char                Character
 * boolean            Boolean
 * 
 * 用於基本數據類型與字符串之間的轉換。
public class IntegerDemo {
    public static void main(String[] args) {
        // 不麻煩的就來了,冒號為查閱API信息
        // public  static String toBinaryString(int i)
        System.out.println (Integer.toBinaryString(100));
        // public  static String toOctalString(int i)
        System.out.println(Integer.toOctalString(100));
        // public  static String toHexString(int i)
        System.out.println(Integer.toHexString(100));
 
        // public  static final int MAX_VALUE
        System.out.println(Integer.MAX_VALUE);
        // public  static final int MIN_VALUE
        System.out.println(Integer.MIN_VALUE);
    }
}
 
20.Integer的構造方法
兩種方法
 *  public Integer(int value)
 * public Integer(String s)
 *         注意: 這個字符串必須是由數字字符組成
 */
public class IntegerDemo {
    public static void main(String[] args) {
        //  方式1
        int i = 100;
        Integer ii = new Integer(i);
        System.out.println("ii:" + ii);// 輸出的不是地址,證明已重寫toString方法
 
        //  方式2
         String s = "100";
        // NumberFormatException
        //  String s = "abc"; (報錯)
        Integer iii = new Integer(s);
        System.out.println("iii:" + iii);
    }
}
 
21 .int類型和String類型的相互轉換
int -- String
 *          String.valueOf(number)
 * 
 * String --  int
 *          Integer.parseInt(s)
public class IntegerDemo {
    public static void main(String[] args) {
        //  int -- String
        int number = 100;
        // 方式1
        String s1 = "" + number;
        System.out.println("s1:" + s1);
         // 方式2
        String s2 = String.valueOf(number);
        System.out.println("s2:" + s2);
        // 方式3
        // int -- Integer -- String
        Integer i = new Integer(number);
        String s3 = i.toString();
        System.out.println("s3:" + s3);
        // 方式4
        // public static String toString(int i)
        String s4 = Integer.toString(number);
        System.out.println("s4:" + s4);
        System.out.println("-----------------");
 
        //  String -- int
        String s = "100";
        // 方式1
        // String -- Integer -- int
        Integer ii = new Integer(s);
        // public int intValue()
        int x = ii .intValue();
        System.out.println("x:" + x);
         //方式2
        //public static int parseInt(String s)
        int y = Integer.parseInt(s);
        System.out.println("y:"+y);
    }
}
 
22.常用的基本進制轉換
 * public static String toBinaryString(int i)
 * public static String toOctalString(int i)
 * public static String toHexString(int i)
 
 
 * 
 * 十進制到其他進制
 * public static String  toString( int i,int radix)
 *  由這個我們也看到了進制的范圍:2-36
 * 為什么呢?0,...9,a...z(10+26)
 * 
 * 其他進制到十進制
 * public static int  parseInt( String s,int radix)
 
//示例
// 十進制到二進制,八進制,十六進制
        System.out.println(Integer.toBinaryString(100));
        System.out.println(Integer.toOctalString(100));
        System.out.println(Integer.toHexString(100));
        System.out.println("-------------------------");
 
 
// NumberFormatException
         //System.out.println(Integer.parseInt("123", 2));(報錯原因:123不是合法的二進制表示)
23.JDK5的新特性自動裝箱和拆箱
 
 
// 定義了一個int類型的包裝類類型變量i
         // Integer i = new Integer(100);
        Integer ii = 100;
        ii += 200;
        System.out.println("ii:" + ii);
 
        // 通過 反編譯后的代碼
        // Integer ii = Integer. valueOf(100); // 自動裝箱
        // ii = Integer.valueOf(ii. intValue() + 200); // 自動拆箱,再自動裝箱
        // System.out.println((new StringBuilder("ii:")).append(ii).toString());
 
 

        Integer iii =  null;
        //  NullPointerException(注意空指針異常)
        if (iii != null) {
            iii += 1000;
            System.out.println(iii);
        }
24.Integer面試題
 
/*
 * 看程序寫結果(since JDK 1.5)
 * 
 * 注意: Integer的數據直接賦值,如果在-128到127之間,會直接從緩沖池里獲取數據(不會再通過new來創建)
 */
public class IntegerDemo {
    public static void main(String[] args) {
        Integer i1 = new Integer(127);
        Integer i2 = new Integer(127);
        System.out.println(i1 == i2);
        System.out.println(i1.equals(i2));
        System.out.println("-----------");
 
        Integer i3 = new Integer(128);
        Integer i4 = new Integer(128);
        System.out.println(i3 == i4);
        System.out.println(i3.equals(i4));
        System.out.println("-----------");
 
         Integer i5 = 128;
        Integer i6 = 128;
        System.out.println(i5 == i6);
        System.out.println(i5.equals(i6));
        System.out.println("-----------");
 
         Integer i7 = 127;
        Integer i8 = 127;
        System.out.println(i7 == i8);
        System.out.println(i7.equals(i8));
 
        // 通過查看源碼,我們就知道了, 針對-128到127之間的數據,做了一個數據緩沖池,如果數據是該范圍內的,每次並不創建新的空間
        // Integer ii = Integer. valueOf(127);//反編譯查詢
    }
}
圖解
equals方法被重寫過,所以 比較的是內容,均為true;
 
 
查源碼(跟蹤valueOf方法)
 
跟蹤low
 
25.Character類
構造方法
、Character 類在對象中包裝一個基本類型 char 的值
 * 此外,該類提供了幾種方法,以確定字符的類別(小寫字母,數字,等等),並將字符從大寫轉換成小寫,反之亦然
 * 
 *  構造方法:
 *         Character(char value)
 
Character ch = new Character('a');
        System.out.println("ch:" + ch); //輸出ch:a    toString方法重寫
26.Character類的常用方法
public static boolean isUpperCase(char ch):判斷給定的字符是否是大寫字符
 * public  static boolean isLowerCase(char ch):判斷給定的字符是否是小寫字符
 * public  static boolean isDigit(char ch):判斷給定的字符是否是數字字符
 * public  static char toUpperCase(char ch):把給定的字符轉換為大寫字符
 * public  static char toLowerCase(char ch):把給定的字符轉換為小寫字符
舉例
System.out.println("isUpperCase:" + Character.isUpperCase('A'));
System.out.println("isLowerCase:" + Character.isLowerCase('a'));
System.out.println("isDigit:" + Character.isDigit('0'));
 
 
 
day14
1.
l 正則表達式:是指一個用來描述或者匹配一系列符合某個句法規則的字符串的單個字符串。其實就是一種規則。有自己特殊的應用。
l
l舉例:校驗qq號碼.

  1:要求必須是5-15位數字

  2:0不能開頭

=================================================================

不用正則表達式的做法

import java.util.Scanner;
 
/*
 * 校驗qq號碼.
 *         1:要求必須是5-15位數字
 *         2:0不能開頭
 * 
 * 分析:
 *         A:鍵盤錄入一個QQ號碼
 *         B:寫一個功能實現校驗
 *         C:調用功能,輸出結果。
 */
public class RegexDemo {
    public static void main(String[] args) {
        // 創建鍵盤錄入對象
        Scanner sc = new Scanner(System.in);
        System.out.println("請輸入你的QQ號碼:");
        String qq = sc.nextLine();
 
        System.out.println("checkQQ:"+checkQQ(qq));
    }
 
    /*
     * 寫一個功能實現校驗 兩個明確: 明確返回值類型:boolean 明確參數列表:String qq
     */
     public static boolean checkQQ(String qq) {
        boolean flag = true;
 
        // 校驗長度
        if (qq.length() >= 5 && qq.length() <= 15) {
            // 0不能開頭
            if (!qq.startsWith("0")) {
                // 必須是數字
                char[] chs = qq.toCharArray();
                for (int x = 0; x < chs.length; x++) {
                    char ch = chs[x];
                    if (!Character.isDigit(ch)) {
                        flag = false;
                        break;
                    }
                }
            } else {
                flag = false;
            }
        } else {
            flag = false;
        }
 
        return flag;
    }
}
 
用正則表達式改進
下圖---String類中的API
 
/*
 * 正則表達式:符合一定規則的字符串。
 */
public class RegexDemo2 {
    public static void main(String[] args) {
        // 創建鍵盤錄入對象
        Scanner sc = new Scanner(System.in);
        System.out.println("請輸入你的QQ號碼:");
        String qq = sc.nextLine();
 
        System.out.println("checkQQ:" + checkQQ(qq));
    }
 
    public static boolean checkQQ(String qq) {
         // String regex ="[1-9][0-9]{4,14}";
        // //public boolean matches(String regex)告知此字符串是否匹配給定的正則表達式
        // boolean flag = qq.matches(regex);
        // return flag;
 
        //return qq.matches("[1-9][0-9]{4,14}");//簡化版,一行代碼
 
        return qq.matches("[1-9]\\d{4,14}");
    }
}
 
2 .正則表達式的規則 
規則字符在java.util.regexPattern類中
A:字符
    x 字符 x。舉例:'a'表示字符a(任意的字符表示它本身)
    \\ 反斜線字符。("\\"表示反斜線\)
    \n 新行(換行)符 ('\u000A') 
    \r 回車符 ('\u000D')
B:字符類(把很多字符都放到一起)
    [abc] a、b   c(簡單類)(意為匹配三選一,但不能同時匹配兩個,例如ab) 
    [^abc] 任何字符,除了 a、b  或 c(否定) 
    [a-zA-Z] a到 z 或 A到 Z,兩頭的字母包括在內(范圍) (這個寫法就意味着包括了所有英文字母)
    [0-9] 0到9的字符都包括
 
例如上面:[1-9][0-9]{4,14}
代表qq號碼第一個數字在1~9范圍之內(也就是不能為零),第二個數字開始(后面的{4,14}規定了除了第一個數字之外,還包含了4~14之間任意的數字個數,而這些數字的取值范圍就在0-9之間)(總的來說就是qq號碼一共是5-15個數字,其中第一個數字不能為零,剩余的4-14個數字可以為零)
 
C:預定義字符類(\有轉義字符的意思)
    . 任何字符。我的就是.字符本身,怎么表示呢? \.
    \d 數字:[0-9]
例如上面: [1-9][0-9]{4,14}可以改寫為[1-9]\\d{4,14}
     \w 單詞字符:[a-zA-Z_0-9]
        在正則表達式里面 組成單詞的東西必須有這些東西組成
D:邊界匹配器
    ^ 行的開頭 
    $ 行的結尾 
    \b 單詞邊界
        就是不是單詞字符的地方。(單詞與單詞之間隔開的東西,如下面單詞與單詞之間的空格,還有?;)
        舉例:hello world?haha;xixi
E:Greedy 數量詞 
    X? X,一次或一次也沒有(0次或者1次)
    X* X,零次或多次(0次或者1次以上)
    X+ X,一次或多次
    X{n} X,恰好 n 次 
    X{n,} X,至少 n 次 
    X{n,m} X,至少 n 次,但是不超過 m 次 
例如上面:[1-9][0-9]{4,14}代表[0-9]至少出現4次但不超過14次([1-9]不給出次數,默認為一次)
3.
 *  判斷功能
 *         String類的public boolean matches(String regex)
 *
 * 需求:
 *         判斷手機號碼是否滿足要求?
 * 
 * 分析:
 *         A:鍵盤錄入手機號碼
 *         B:定義手機號碼的規則
 *             13436975980
 *             13688886868
 *             13866668888
 *             13456789012
 *             13123456789
 *             18912345678
 *             18886867878
 *             18638833883
 *         C:調用功能,判斷即可
 *         D:輸出結果
 */
public class RegexDemo {
    public static void main(String[] args) {
        //鍵盤錄入手機號碼
        Scanner sc = new Scanner(System.in);
        System.out.println("請輸入你的手機號碼:");
        String phone = sc.nextLine();
 
        //定義手機號碼的規則
        String regex = "1[38]\\d{9}";
 
        //調用功能,判斷即可
        boolean flag = phone.matches(regex);
 
        //輸出結果
        System.out.println("flag:"+flag);
    }
}
4.校驗郵箱案例(判斷功能)
import java.util.Scanner;
 
/*
 * 校驗郵箱
 * 
 * 分析:
 *         A:鍵盤錄入郵箱
 *         B:定義郵箱的規則
 *              1517806580@qq.com
 *              liuyi@163.com
 *              linqingxia@126.com
 *              fengqingyang@sina.com.cn
 *              fqy@itcast.cn
 *         C:調用功能,判斷即可
 *         D:輸出結果
 */
public class RegexTest {
    public static void main(String[] args) {
        //鍵盤錄入郵箱
        Scanner sc = new Scanner(System.in);
        System.out.println("請輸入郵箱:");
        String email = sc.nextLine();
 
        //定義郵箱的規則
        //String regex = "[a-zA-Z_0-9]+@[a-zA-Z_0-9]{2,6} (\\.[a-zA-Z_0-9]{2,3})+";
         String regex = "\\w+@\\w{2,6}(\\.\\w{2,3})+";
 
        //調用功能,判斷即可
        boolean flag = email.matches(regex);
 
        //輸出結果
        System.out.println("flag:"+flag);
    }
}
5.正則表達式 分割功能
String類的public String[] split(String regex)
    根據給定正則表達式的匹配拆分此字符串。
 
/*舉例:
          百合網,世紀佳緣,珍愛網,QQ
        搜索好友
            性別:女
               范圍:"18-24"
 
         age>=18 && age<=24
*/
public class RegexDemo {
    public static void main(String[] args) {
        //定義一個年齡搜索范圍
        String ages =  "18-24";
 
        //定義規則
         String regex = "-";
 
        //調用方法
         String[] strArray = ages. split(regex);
 
//        //遍歷
//        for(int x=0; x<strArray.length; x++){
//            System.out.println(strArray[x]);
//        }
 
         //如何得到int類型的呢?
        int startAge = Integer.parseInt(strArray[0]);
        int endAge = Integer.parseInt(strArray[1]);
 
        //鍵盤錄入年齡
        Scanner sc = new Scanner(System.in);
        System.out.println("請輸入你的年齡:");
        int age = sc.nextInt();
 
        if(age>=startAge && age<=endAge) {
            System.out.println("你就是我想找的");
        }else {
            System.out.println("不符合我的要求,gun");
        }
    }
}
6.分隔功能練習
 
public class RegexDemo2 {
    public static void main(String[] args) {
        // 定義一個字符串
        String s1 = "aa,bb,cc";
        // 直接分割   split(regex)
         String[] str1Array = s1.split(",");
        for (int x = 0; x < str1Array.length; x++) {
            System.out.println(str1Array[x]);
        }
        System.out.println("---------------------");
 
        String s2 = "aa.bb.cc";
         String[] str2Array = s2.split("\\.");//注意這里 不能直接寫點號,因為在正則表達式里面點號表示任意字符
                                                              //,應該用\\.
        for (int x = 0; x < str2Array.length; x++) {
            System.out.println(str2Array[x]);
        }
        System.out.println("---------------------");
 
        String s3 = "aa    bb                cc";
        String[] str3Array = s3.split(" +");//這里寫的regex的意思是任意多個的空格(+前面的空格代表空格,而+表示
                                                               //空格 有 一次或者一次以上)
        for (int x = 0; x < str3Array.length; x++) {
            System.out.println(str3Array[x]);
        }
        System.out.println("---------------------");
 
        //硬盤上的路徑,我們應該用\\替代\
         String s4 = "E:\\JavaSE\\day14\\avi";
        String[] str4Array = s4.split("\\\\");//注意這里是 4個杠!!
        for (int x = 0; x < str4Array.length; x++) {
            System.out.println(str4Array[x]);
        }
        System.out.println("---------------------");
    }
}
7.分隔功能案例
我有如下一個字符串:"91 27 46 38 50"
 請寫代碼實現最終輸出結果是:"27 38 46 50 91"
import java.util.Arrays;
 
/*
 * 分析:
 *          A:定義一個字符串
 *         B:把字符串進行分割,得到一個字符串數組
 *         C:把字符串數組變換成int數組
 *         D:對int數組排序
 *         E:把排序后的int數組在組裝成一個字符串
 *         F:輸出字符串
 */
public class RegexTest {
    public static void main(String[] args) {
        // 定義一個字符串
        String s = "91 27 46 38 50";
 
        // 把字符串進行分割,得到一個字符串數組
        String[] strArray = s.split(" ");
 
         // 把字符串數組變換成int數組
        int[] arr = new int[strArray.length];
 
        for (int x = 0; x < arr.length; x++) {
            arr[x] = Integer.parseInt(strArray[x]);
        }
 
        // 對int數組排序
        Arrays.sort(arr);
 
       // 把排序后的int數組在組裝成一個字符串(不能直接調用toString方法,因為數字之間由空格隔開而不是逗號隔開)
        StringBuilder sb = new StringBuilder();
        for (int x = 0; x < arr.length; x++) {
            sb.append(arr[x]).append(" ");
        }
        //轉化為字符串
        String result = sb. toString().trim();//這里的toString方法是StringBuilder 轉換成String類型的過程,
                                                                //trim()方法旨在去掉字符串最后一個空格
 
        //輸出字符串
        System.out.println("result:"+result);
    }
}
8.正則表達式替換功能
     String類的 public String replaceAll(String regex,String replacement)
     使用給定的 replacement 替換此字符串所有匹配給定的正則表達式的子字符串。
public class RegexDemo {
    public static void main(String[] args) {
        // 定義一個字符串
        String s = "helloqq12345worldkh622112345678java";
 
        // 我要去除所有的數字,用*給替換掉
        // String  regex = "\\d+";
        // String regex = "\\d";
        //String  ss = "*";
 
 
        // 直接把數字干掉
        String regex = "\\d+";
        String ss = "";
 
        String result = s.replaceAll(regex, ss);
        System.out.println(result);
    }
}
 
9.Pattern和Matcher的概述
 
10.正則表達式的獲取功能
 
 
 
 
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
/*
 * 獲取功能:
 * 獲取下面這個字符串中由三個字符組成的單詞
 * da jia ting wo shuo,jin tian yao xia yu,bu shang wan zi xi,gao xing bu?
 */
public class RegexDemo2 {
    public static void main(String[] args) {
        // 定義字符串
        String s = "da jia ting wo shuo,jin tian yao xia yu,bu shang wan zi xi,gao xing bu?";
        // 規則
        String regex = "\\b\\w{3}\\b";
 
        // 把規則編譯成模式對象
        Pattern p = Pattern.compile(regex);
        // 通過模式對象得到匹配器對象
        Matcher m = p.matcher(s);
        // 調用匹配器對象的功能
        // 通過find方法就是查找有沒有滿足條件的 子串
        //  public boolean find()
        // boolean flag = m.find();
        // System.out.println(flag);
        // // 如何得到值呢?
        // //  public String group()
        // String ss = m.group();
        // System.out.println(ss);
   
         while (m.find()) {
            System.out.println(m.group());
        }
 
        // 注意: 一定要先find(),然后才能group()
        // IllegalStateException: No match found
        // String ss = m.group();
        // System.out.println(ss);
    }
}
 
簡化如下
public class RegexDemo2 {
    public static void main(String[] args) {
        // 定義一個字符串
        String s = "da jia ting wo shuo,jin tian yao xia yu,bu shang wan zi xi,gao xing bu?";
 
        // 定義規則
        String regex = "\\b\\w{3}\\b";
 
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(s);
        // boolean b = m.find();
        while (m.find()) {
            System.out.println(m.group());
        }
 
    }
}
 
11.Math類
Math:用於數學運算的類。
  成員變量:
          public static final double PI
         public static final double E
  成員方法:
          public static int abs(int a):絕對值
         public static  double  ceil(double a): 向上取整
         public static  double  floor(double a): 向下取整
        public static int max(int a,int b):最大值 (min自學)
         public static double  pow(double a,double b):a的b次冪
         public static double random():隨機數 [0.0,1.0)
         public static  int round( float a) 四舍五入(參數為double的自學)
         public static  double sqrt(double a): 平方根
舉例:
 
        // public static double ceil(double a):向上取整(與四舍五入無關)
        System.out.println("ceil:" + Math.ceil(12.34));//ceil: 13.0
        System.out.println("ceil:" + Math.ceil(12.56));//ceil: 13.0
        System.out.println("--------------");
 
        // public static double floor(double a):向下取整(與四舍五入無關)
        System.out.println("floor:" + Math.floor(12.34));//floor:12.0
        System.out.println("floor:" + Math.floor(12.56));//floor:12.0
        System.out.println("--------------");
 
 
最大值應用舉例
// public static int max(int a,int b):最大值
        System.out.println("max:" + Math.max(12, 23));
        // 需求:我要獲取 三個數據中的最大值
        //  方法的嵌套調用
        System.out.println("max:" + Math. max(Math .max(12, 23), 18));
        // 需求:我要獲取四個數據中的最大值
        System.out.println("max:"
                + Math. max(Math. max(12, 78), Math. max(34, 56)));
        System.out.println("--------------");
 
隨機數舉例
// 獲取一個1-100之間的隨機數
        System.out.println("random:" +  ((int) (Math.random() * 100) + 1));//注意這里的 優先級!!少了外層的括號 
                                                                                                // random將與前面的字符串拼接形成類似於981的數
        System.out.println("--------------");
 
 
四舍五入舉例
System.out.println("round:" + Math.round(12.34f));//round:12
  System.out.println("round:" + Math.round(12.56f));//round:13
round原理如下圖:
 
12.一道面試題
需求:請設計一個方法,可以 實現獲取任意范圍內的隨機數
 
  分析:
          A:鍵盤錄入兩個數據。
              int start;
              int end;
          B:想辦法獲取在start到end之間的隨機數
              我寫一個功能實現這個效果,得到一個隨機數。(int)
          C:輸出這個隨機數
 
public class MathDemo {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("請輸入開始數:");
        int start = sc.nextInt();
        System.out.println("請輸入結束數:");
        int end = sc.nextInt();
 
        for (int x = 0; x < 100; x++) {      //這里的for循環是為了 多測試幾組數據,非必要。
            // 調用功能
            int num = getRandom(start, end);
            // 輸出結果
            System.out.println(num);
        }
    }
 
    /*
     * 寫一個功能 兩個明確: 返回值類型:int 參數列表:int start,int end
     */
    public static int getRandom(int start, int end) {
         // 回想我們講過的1-100之間的隨機數
        // int number = (int) (Math.random() * 100) + 1;
        // int number = (int) (Math.random() * end) + start;
        // 發現有問題了,怎么辦呢?
        int number = (int) (Math.random() * (end - start + 1)) + start;
        return number;
    }
}
13.Random類
Random:產生隨機數的類
import java.util.Random;
構造方法:
         public Random():沒有給種子,用的是 默認種子是當前時間的毫秒值
         public Random(long seed):給出指定的種子
 
         給定種子后,每次得到的隨機數是相同的。
 
  成員方法:
          public int nextInt():返回的是int范圍內的隨機數
         public int nextInt(int n):返回的是[0,n)范圍的內隨機數
 
舉例
public class RandomDemo {
    public static void main(String[] args) {
        // 創建對象
        // Random r = new Random();
        Random r = new Random(1111);
 
        for (int x = 0; x < 10; x++) {
            // int num = r.nextInt();
             int num = r.nextInt(100) + 1;
            System.out.println(num);
        }
    }
}
 
14.System類
 
 
System.gc()

System.gc()可用於垃圾回收。當使用System.gc()回收某個對象所占用的內存之前,通過要求程序調用適當的方法來清理資源。在沒有明確指定資源清理的情況下,Java提高了默認機制來清理該對象的資源,就是調用Object類的finalize()方法。finalize()方法的作用是釋放一個對象占用的內存空間時,會被JVM調用。而子類重寫該方法,就可以清理對象占用的資源,該方法有沒有鏈式調用,所以必須手動實現。

 

 

 

從程序的運行結果可以發現,執行System.gc()前,系統會自動調用finalize()方法清除對象占有的資源,通過super.finalize()方式可以實現從下到上的finalize()方法的調用,即先釋放自己的資源,再去釋放父類的資源。

但是,不要在程序中頻繁的調用垃圾回收,因為每一次執行垃圾回收,jvm都會強制啟動垃圾回收器運行,這會耗費更多的系統資源,會與正常的Java程序運行爭搶資源,只有在執行大量的對象的釋放,才調用垃圾回收最好

15.System.exit(0)

public static void exit(int status):終止當前正在運行的 Java 虛擬機。參數用作狀態碼;根據慣例,非 0 的狀態碼表示異常終止。(0表示正常)
所以,建議用exit(0);
16.System類 currentTimeMillis()
 
System.out.println(System.currentTimeMillis());
 
        單獨得到這樣的實際目前對我們來說意義不大
         那么,它到底有什么作用呢?
         要求:請大家給我統計這段程序的運行時間
         long start = System.currentTimeMillis();
        for (int x = 0; x < 100000; x++) {
            System.out.println("hello" + x);
        }
         long end = System.currentTimeMillis();
        System.out.println( "共耗時:" + (end - start) + "毫秒");
    }
 
 
17.system類 arraycopy(注意,arraycopy並不符合命名規則(since JDK1.0),但是不改了)
public static void arraycopy(Object src,int srcPos,Object dest,int destPos,int length)
   從指定源數組中復制一個數組,復制從指定的位置開始,到目標數組的指定位置結束。
舉例
 
        int[] arr = { 11, 22, 33, 44, 55 };
        int[] arr2 = { 6, 7, 8, 9, 10 };
 
        System.arraycopy(arr, 1, arr2, 2, 2);
 
        System.out.println( Arrays.toString(arr));//[11, 22, 33, 44, 55]
 
        System.out.println( Arrays.toString(arr2));//[6, 7,  22, 33, 10]
 
注意Arrays.toString(……)方法
 
18.BigInteger類---可以讓 超過 Integer范圍內的數據進行運算(即 超過2147483647)
java.math.BigInteger
public BigInteger  add(BigInteger val):加
 public BigInteger  subtract(BigInteger val):減
  public BigInteger  multiply(BigInteger val):乘
 public BigInteger divide(BigInteger val):除
  public  BigInteger[]  divideAndRemainder(BigInteger val):返回 商和余數的數組
 
 
BigInteger bi1 = new BigInteger("100");
 BigInteger bi2 = new BigInteger("50");
 
BigInteger[] bis = bi1.divideAndRemainder(bi2);
 System.out.println(" :" + bis[0]);//2
 System.out.println(" 余數:" + bis[1]);//0
 
19.   BigDecimal
由於在運算的時候,float類型和double很容易丟失精度,演示案例。所以,為了能精確的表示、計算浮點數,Java提供了BigDecimal
 
public BigInteger add(BigInteger val):加
 * public BigInteger subtract(BigInteger val):減
 * public BigInteger multiply(BigInteger val):乘
 * public BigInteger divide(BigInteger val):除
 * public BigInteger[] divideAndRemainder(BigInteger val):返回商和余數的數組
 

divisor  - 此 BigDecimal 要除以的值。 scale  - 要返回的 BigDecimal 商的標度。(也就是保留多少位小數) roundingMode  - 要應用的舍入模式。(一般用ROUND_HALF_UP----即四舍五入)
 
 
20.Date類
 
Date:表示特定的瞬間,精確到毫秒。
Date的構造方法
        Date():根據當前的默認毫秒值創建日期對象
       Date(long date):根據給定的 毫秒值創建日期對象
 
獲取當前時間
long time = System.currentTimeMillis();
Date d2 = new Date(time);
System.out.println("d2:" + d2);
 
21.Date類的一些方法
public long getTime():獲取時間,以毫秒為單位
 public void setTime(long time):設置時間
 
掌握兩個方法(轉換)
從Date得到一個毫秒值
          getTime()
   把一個毫秒值轉換為Date
         構造方法
         setTime(long time)
 
/ 創建對象
        Date d = new Date();
 
        // 獲取時間
         long time = d. getTime();
        System.out.println(time);
        // System.out.println(System. currentTimeMillis());
 
        System.out.println("d:" + d);
        // 設置時間
        d.setTime(1000);//1000代表1000毫秒
        System.out.println("d:" + d);
 
22.DateFormat
String和Date的相互轉換理解
 
Date     --     String(格式化)
          public final String  format(Date date)(這個是具體子類SimpleDateFormat的 父類DateForamt中的一個方法)
  
  String -- Date(解析)
         public Date parse(String source)
 
  DateForamt:可以進行日期和字符串的格式化和解析,但是由於是抽象類,所以使用具體子類SimpleDateFormat。
 
// Date -- String
        // 創建日期對象
        Date d = new Date();
        // 創建格式化對象
        // SimpleDateFormat sdf = new SimpleDateFormat();
        // 給定模式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
        // public final String format(Date date)
        String s =  sdf.format(d);//子類調用父類的方法
        System.out.println(s);
基礎輸出
 
總結:
Date     --     String(格式化)
         public final String format(Date date)
  
   String -- Date(解析)
          public Date parse(String source)
  
  DateForamt:可以進行日期和字符串的格式化和解析,但是由於是抽象類,所以使用具體子類SimpleDateFormat。
  
  SimpleDateFormat的構造方法:
         SimpleDateFormat():默認模式
         SimpleDateFormat(String pattern):給定的模式
              這個模式字符串該如何寫呢?
             通過查看API,我們就找到了對應的模式
             
 年 y
              月 M    
              日 d
              時 H
              分 m
              秒 s
           2014年12月12日 12:12:12
 
具體方法
-1-. 日期轉字符串
Date d = new Date();
SimpleDateFormat sdf = new SimpleDateFormat(" yyyy年MM月dd日 HH:mm:ss");//給定模式
String s = sdf. format(d);//format意為格式化
System.out.println(s);
輸出如下
 
-2- 字符串轉日期
String str = "2008-08-08 12:12:12";
//在把一個字符串解析為日期的時候, 請注意格式必須和給定的字符串格式匹配
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date dd = sdf2. parse(str);//parse意為解析
 
 

23.Date類一個綜合案例----你來到這個世界多少天
你來到這個世界多少天
分析:
          A:鍵盤錄入你的出生的年月日
          B:把該字符串轉換為一個日期
          C:通過該日期得到一個毫秒值
          D:獲取當前時間的毫秒值
          E:用D-C得到一個毫秒值
          F:把E的毫秒值轉換為年
                                 /1000/60/60/24
本人寫法
輸出測試結果
 
24.Calendar類(抽象類)以及getInstance()和get()方法
Calendar:它為特定瞬間與一組諸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等 日歷字段之間的轉換提供了一些方法,並為操作日歷字段(例如獲得下星期的日期)提供了一些方法。
  
  public int get(int field):返回給定日歷 字段的值。日歷類中的每個日歷字段都是 靜態的成員變量,並且是 int類型
下圖解析 Calendar rightNow =  Calendar.getInstance(); (運用了 多態)(具體可查API)
 
// 其日歷字段已由當前日期和時間初始化:
        Calendar rightNow =  Calendar.getInstance(); // 子類對象
 
        // 獲取年
        int year = rightNow. get(Calendar.YEAR);
        // 獲取月
        int month = rightNow. get(Calendar.MONTH);
        // 獲取日
        int date = rightNow. get(Calendar.DATE);
 
        System.out.println(year + "年" +  (month + 1) + "月" + date + "日");
 
25.Calendar類另外兩個方法
public void  add(int field,int amount):根據給定的日歷字段和對應的時間,來對當前的日歷進行操作。(amount可以是負的)
 public final void  set(int year,int month,int date):設置當前日歷的年月日
 
承接上一節的獲取時間
三年前的今天
 
5年10天前
 
注意set 方法中的month小問題( month從0開始)
 
附:Calendar也有獲得毫秒值的方法(具體看API)
 
26.一個小案例------獲取任意一年的二月有多少天
 
import java.util.Calendar;
import java.util.Scanner;
 
/*
 * 獲取任意一年的二月有多少天(注意month從0開始)
 * 
 *  分析:
 *         A:鍵盤錄入任意的年份
 *         B:設置日歷對象的年月日
 *             年就是A輸入的數據
 *             月是2
 *             日是1
 *         C:把時間往前推一天,就是2月的最后一天
 *         D:獲取這一天輸出即可
 */
public class CalendarTest {
    public static void main(String[] args) {
        // 鍵盤錄入任意的年份
        Scanner sc = new Scanner(System.in);
        System.out.println("請輸入年份:");
        int year = sc.nextInt();
 
        // 設置日歷對象的年月日
        Calendar c = Calendar.getInstance();
        c.set(year, 2, 1); // 其實是這一年的3月1日
        // 把時間往前推一天,就是2月的最后一天
        c.add(Calendar.DATE, -1);
 
        // 獲取這一天輸出即可
        System.out.println(c.get(Calendar.DATE));
    }
}
 
day14補充
Calendar
    (1)日歷類,封裝了所有的日歷字段值,通過 統一的方法根據傳入不同的日歷字段可以獲取值。
    (2)如何得到一個日歷對象呢?
        Calendar rightNow = Calendar.getInstance();
         本質返回的是子類對象
 
day15
1.對象數組的內存圖解
 
2.集合概述
集合的由來:
          我們學習的是面向對象語言,而面向對象語言對事物的描述是通過對象體現的,為了方便對多個對象進行操作,我們就必須把這多個對象進行存儲。
          而要想存儲多個對象,就不能是一個基本的變量,而應該是一個容器類型的變量,在我們目前所學過的知識里面,有哪些是容器類型的呢?
           數組和StringBuffer。但是呢?StringBuffer的結果是一個字符串,不一定滿足我們的要求,所以我們只能選擇數組,這就是對象數組。
          而對象數組又不能適應變化的需求,因為數組的長度是固定的,這個時候,為了適應變化的需求,Java就提供了集合類供我們使用。
 
3.數組和集合的區別?
          A:長度區別
              數組的長度固定
              集合 長度可變
          B:內容不同
              數組存儲的是同一種類型的元素
              而集合可以存儲不同類型的元素
          C:元素的數據類型問題    
              數組可以存儲基本數據類型,也可以存儲引用數據類型
              集合 只能存儲引用類型
 
3.集合的繼承體系圖解
4.Collection
Collection:是集合的頂層接口,它的子體系有重復的,有唯一的,有有序的,有無序的。
  
  Collection的 功能概述
  1:添加功能
         boolean add(Object obj):添加一個元素
          boolean addAll(Collection c):添加一個集合的元素
  2:刪除功能
          void clear():移除所有元素
          boolean remove(Object o):移除一個元素
          boolean removeAll(Collection c):移除一個集合的元素(是一個還是所有)
  3:判斷功能
          boolean contains(Object o):判斷集合中是否包含指定的元素
          boolean containsAll(Collection c):判斷集合中是否包含指定的集合元素(是一個還是所有)
          boolean isEmpty():判斷集合是否為空
  4:獲取功能
           Iterator<E> iterator()(重點)
  5:長度功能
          int  size():元素的個數
         
 面試題:數組有沒有length()方法呢?字符串有沒有length()方法呢?集合有沒有length()方法呢?
  6:交集功能
          boolean retainAll(Collection c):兩個集合都有的元素?思考元素去哪了,返回的boolean又是什么意思呢?
 7:把集合轉換為數組
          Object[] toArray()
5.重點注意幾個All方法
boolean addAll(Collection c):添加一個集合的元素
 boolean removeAll(Collection c):移除一個集合的元素(是一個還是所有)
 boolean containsAll(Collection c):判斷集合中是否包含指定的集合元素(只有包含 所有的元素,才叫包含)
  boolean retainAll(Collection c):兩個集合都有的元素?思考元素去哪了,返回的boolean又是什么意思呢?
 
addAll示例
removeAll示例(只要有一個元素被移除了,就返回true)
注意
boolean retainAll(Collection c):兩個集合都有的元素?思考元素去哪了,返回的boolean又是什么意思呢?
        //假設有兩個集合A,B。
        //A對B做交集,最終的結果保存在A中,B不變。
        // 返回值表示的是A是否發生過改變。
 
 
 
 
 
返回值表示的是A(原集合)是否發生過改變。
 
6.集合的遍歷
集合的遍歷,其實就是依次獲取集合中的每一個元素。
Object[] toArray():把集合轉成數組,可以實現集合的遍歷
 
// 創建集合對象
        Collection c = new ArrayList();
 
        // 添加元素
        c.add("hello"); // 這個語句隱含有Object obj = "hello"; 向上轉型
        c.add("world");
        c.add("java");
 
        // 遍歷
        // Object[] toArray():把集合轉成數組,可以實現集合的遍歷
        Object[] objs =  c.toArray();
        for (int x = 0; x < objs.length; x++) {
            // System.out.println(objs[x]);
            // 我知道元素是字符串,我在獲取到元素的的同時, 還想知道元素的長度
            // System.out.println(objs[x] + "---" + objs[x].length());
            // 上面的實現不了,原因是 Object中沒有length()方法
            // 我們要想使用字符串的方法,就必須把元素還原成字符串
            //  向下轉型
            String s =  (String) objs[x];
            System.out.println(s + "---" + s.length());
7.集合的遍歷案例(最原始的遍歷方式,以后不常用,用迭代器取代)
練習:用集合存儲5個學生對象,並把學生對象進行遍歷。
 * 
 * 分析:
 * A:創建學生類
 * B:創建集合對象
 * C:創建學生對象
 * D:把學生添加到集合
 * E:把集合轉成數組
 * F:遍歷數組
 
 
public class StudentDemo {
    public static void main(String[] args) {
        // 創建集合對象
        Collection c = new ArrayList();
 
        // 創建學生對象
        Student s1 = new Student("林青霞", 27);
        Student s2 = new Student("風清揚", 30);
        Student s3 = new Student("令狐沖", 33);
        Student s4 = new Student("武鑫", 25);
        Student s5 = new Student("劉曉曲", 22);
 
        // 把學生添加到集合
        c.add(s1);
        c.add(s2);
        c.add(s3);
        c.add(s4);
        c.add(s5);
 
        // 把集合轉成數組
        Object[] objs = c.toArray();
         // 遍歷數組
        for (int x = 0; x < objs.length; x++) {
            // System.out.println(objs[x]);
 
            Student s = (Student) objs[x];
            System.out.println(s.getName() + "---" + s.getAge());
        }
    }
}
所需的同一個包下的Student類如下
 
 
8.Iterator迭代器
Iterator iterator():迭代器,集合的專用遍歷方式
         
 Object next():獲取元素,並移動到下一個位置。
         boolean hasNext():如果仍有元素可以迭代,則返回 true。
典型寫法
Collection c = new ArrayList();
c.add("hello");
c.add("world");
c.add("java");
 
Iterator it = c.iterator(); // 實際返回的肯定是子類對象, 這里是多態
 
while (it.hasNext()) {
            // System.out.println(it.next());//這個其實也可以
            String s =  (String) it.next();//建議 向下轉型
            System.out.println(s);
        }
 
9.注意事項
 
10.迭代器使用圖解和原理解析
 
 
 
迭代器的源碼 Iterator   Iterable  Collection都是接口
 
public interface Iterator {
    boolean hasNext();
    Object next(); 
}
 
public interface Iterable {
    Iterator iterator();//這個方法到這里還沒有實現
}
 
public interface Collection extends  Iterable {
    Iterator iterator();//這個方法到這里還沒有實現
}
 
public interface List extends Collection {
    Iterator iterator();//這個方法到這里還沒有實現
}
 
public class ArrayList  implements List {
    public Iterator iterator() {
        return  new Itr();//這個方法到這里開始實現
    }
 
    private class Itr implements Iterator {
         public boolean hasNext() {}
         public Object next(){} //直到這里上面的接口方法才算真正實現了
    }
}
 
 
Collection c = new ArrayList();
c.add("hello");
c.add("world");
c.add("java");
Iterator it = c.iterator();      //new Itr();
while(it.hasNext()) {
    String s = (String)it.next();
    System.out.println(s);
}
 
11.List接口概述
有序的
 collection(也稱為序列)。此接口的用戶可以對列表中每個元素的插入位置進行精確地控制。用戶可以根據元素的整數索引(在列表中的位置)訪問元素,並搜索列表中的元素。
 set 不同,列表通常允許重復的元素。
 
12.List集合的特有功能:
  A:添加功能
          void add(int index,Object element):在指定位置添加元素
  B:獲取功能
          Object get(int index):獲取指定位置的元素
  C:列表迭代器
          ListIterator listIterator():List集合特有的迭代器
  D:刪除功能
         Object remove(int index):根據索引刪除元素, 返回被刪除的元素
  E:修改功能
          Object set(int index,Object element):根據索引修改元素, 返回被修飾的元素
 
13.ListIterator特有功能
 
public class ListDemo4 {
    public static void main(String[] args) {
        List list = new ArrayList();
 
        list.add("hello");
        list.add("world");
        list.add("java");
 
        L istIterator lit = list.listIterator();
        while ( lit.hasNext()) {
            String s = (String)  lit.next();
            System.out.println(s);
        }
 
        System.out.println("----");
 
        while ( lit.hasPrevious()) {
            String s = (String)  lit.previous();
            System.out.println(s);
        }
 
    }
}
 
14.一個需要注意的問題
問題
       我有一個集合,如下,請問,我想 判斷里面有沒有"world"這個元素,如果有,我就添加一個"javaee"元素,請寫代碼實現。
 
按常理做法結果如下
 
運行有異常
 
ConcurrentModificationException:當方法檢測到對象的並發修改,但不允許這種修改時,拋出此異常。
 
產生的原因:
          迭代器是依賴於集合而存在的,在判斷成功后, 集合的中新添加了元素,而迭代器卻不知道,所以就報錯了,這個錯叫並發修改異常。
          其實這個問題描述的是: 迭代器遍歷元素的時候,通過集合是不能修改元素的
  如何解決呢?
          A: 迭代器迭代元素, 迭代器修改元素
             元素是跟在剛才迭代的元素后面的。
          B: 集合遍歷元素, 集合修改元素(普通for)
              元素在最后添加的。

附:接口 ListIterator<E>有如下幾個方法(迭代器修改元素)

 

方法1如圖

注意javaee被添加的位置
元素是 跟在剛才迭代的元素后面的
 
方法2如圖
 
注意javaee被添加的位置
元素在最后添加的
 
15.數據結構
數據結構:數據的組織形式
面試題: 常見的數據結構的優缺點
(數據結構+算法)
 
16.List的子類特點
List:(面試題List的子類特點)
    ArrayList:
        底層數據結構是數組,查詢快,增刪慢。
        線程不安全,效率高。
    Vector:
        底層數據結構是數組,查詢快,增刪慢。
        線程安全,效率低。
    LinkedList:
        底層數據結構是鏈表,查詢慢,增刪快。
        線程不安全,效率高。
 
    List有三個兒子,我們到底使用誰呢?
        看需求(情況)。
 
    要安全嗎?
        要:Vector(即使要安全,也不用這個,后面有替代的)
        不要:ArrayList或者LinkedList
            查詢多:ArrayList
            增刪多:LinkedList
 
day15補充
集合的繼承體系結構?
        由於需求不同,Java就提供了不同的集合類。這多個集合類的數據結構不同,但是它們都是要提供存儲和遍歷功能的,
        我們把它們的共性不斷的向上提取,最終就形成了集合的繼承體系結構圖。
 
        Collection
            |--List
                |--ArrayList
                |--Vector
                |--LinkedList
            |--Set
                |--HashSet
                |--TreeSet
 
day16
1.ArrayList存儲自定義對象並遍歷
public static void main(String[] args) {
        // 創建集合對象
         ArrayList array = new ArrayList();
 
        // 創建學生對象
        Student s1 = new Student("武松", 30);
        Student s2 = new Student("魯智深", 40);
        Student s3 = new Student("林沖", 36);
        Student s4 = new Student("楊志", 38);
 
        // 添加元素
        array.add(s1);
        array.add(s2);
        array.add(s3);
        array.add(s4);
 
        // 遍歷
        Iterator it =  array.iterator();
        while (it.hasNext()) {
            Student s = (Student) it.next();
            System.out.println(s.getName() + "---" + s.getAge());
        }
 
        System.out.println("----------------");
 
        for (int x = 0; x <  array.size(); x++) {
          
            Student s = (Student)  array.get(x);
            System.out.println(s.getName() + "---" + s.getAge());
        }
    }
 
2.Vector
Vector的特有功能:
 * 1:添加功能
 *         public void addElement(Object obj)        --    被后來的add()替代
 * 2:獲取功能
 *         public Object elementAt(int index)        --  被后來的get()替代
 *         public  Enumeration elements()            --   被后來的Iterator iterator()替代
 *                 boolean hasMoreElements()                被后來的hasNext()替代
 *                 Object nextElement()                   被后來的next()替代
 * 
 * 附:JDK升級的原因:
 *         A:安全
 *         B:效率
 *         C:簡化書寫
 
public static void main(String[] args) {
        // 創建集合對象
        Vector v = new Vector();
 
        // 添加功能
        v.addElement("hello");
        v.addElement("world");
        v.addElement("java");
 
        // 遍歷
        for (int x = 0; x < v.size(); x++) {
            String s = (String) v.elementAt(x);
            System.out.println(s);
        }
 
        System.out.println("------------------");
 
         Enumeration en = v. elements(); // 返回的是實現類的對象
        while (en. hasMoreElements()) {
            String s = (String) en. nextElement();
            System.out.println(s);
        }
    }
3.LinkedList的特有功能:
 *         A:添加功能
 *             public void addFirst(Object e)
 *             public void addLast(Object e)
 *         B:獲取功能
 *             public Object getFirst()
 *             public Obejct getLast()
 *         C:刪除功能
 *             public Object removeFirst()
 *             public Object removeLast()

 

 

4.一個案例
ArrayList去除集合中字符串的重復值(字符串的內容相同)
思路
 
分析:
 *         A:創建集合對象
 *         B:添加多個字符串元素(包含內容相同的)
 *         C:創建新集合
 *         D:遍歷舊集合,獲取得到每一個元素
 *         E: 拿這個元素到新集合去找,看有沒有
 *             有:不搭理它
 *             沒有:就添加到新集合
 *         F:遍歷新集合
 
public static void main(String[] args) {
        // 創建集合對象
        ArrayList array = new ArrayList();
 
        // 添加多個字符串元素(包含內容相同的)
        array.add("hello");
        array.add("world");
        array.add("java");
        array.add("world");
        array.add("java");
        array.add("world");
        array.add("world");
        array.add("world");
        array.add("world");
        array.add("java");
        array.add("world");
 
        // 創建新集合
        ArrayList newArray = new ArrayList();
 
        // 遍歷舊集合,獲取得到每一個元素
        Iterator it = array.iterator();
        while (it.hasNext()) {
            String s = (String) it.next();
 
            // 拿這個元素到新集合去找,看有沒有
            if (!newArray. contains(s)) {
                newArray.add(s);
            }
        }
 
        // 遍歷新集合
        for (int x = 0; x < newArray.size(); x++) {
            String s = (String) newArray.get(x);
            System.out.println(s);
        }
    }
 
這個案例,注意contains(s)的使用,很容易忽(wang)略(ji)這個功能!!。
5.上一個案例的另外一種思路(有點復雜,理解一下就行,常用上一中方法)
需求:ArrayList去除集合中字符串的重復值(字符串的內容相同)
 要求: 不能創建新的集合,就在以前的集合上做。
public static void main(String[] args) {
        // 創建集合對象
        ArrayList array = new ArrayList();
 
        // 添加多個字符串元素(包含內容相同的)
        array.add("hello");
        array.add("world");
        array.add("java");
        array.add("world");
        array.add("java");
        array.add("world");
        array.add("world");
        array.add("world");
        array.add("world");
        array.add("java");
        array.add("world");
 
        //  由選擇排序思想引入,我們就可以通過這種思想做這個題目
        // 拿0索引的依次和后面的比較,有就把后的干掉
        // 同理,拿1索引...
        for (int x = 0; x < array.size() - 1; x++) {
            for (int y = x + 1; y < array.size(); y++) {
                if (array.get(x).equals(array.get(y))) {
                    array.remove(y);
                     y--;
                }
            }
        }
 
        // 遍歷集合
        Iterator it = array.iterator();
        while (it.hasNext()) {
            String s = (String) it.next();
            System.out.println(s);
        }
    }
 
下面解析一下y--的來源,為什么要有y--,
首先,沒有y--,程序結果不對
 
接着,通過設置斷點debug發現
 
最后,通過添加y--解決
 
6.另一個案例
需求:去除集合中 自定義對象的重復值(對象的成員變量值都相同)
自定義對象可以為學生類
 
我們按照和字符串一樣的操作,發現出問題了。
 
public static void main(String[] args) {
        // 創建集合對象
        ArrayList array = new ArrayList();
 
        // 創建學生對象
        Student s1 = new Student("林青霞", 27);
        Student s2 = new Student("林志玲", 40);
        Student s3 = new Student("鳳姐", 35);
        Student s4 = new Student("芙蓉姐姐", 18);
        Student s5 = new Student("翠花", 16);
        Student s6 = new Student("林青霞", 27);
        Student s7 = new Student("林青霞", 18);
 
        // 添加元素
        array.add(s1);
        array.add(s2);
        array.add(s3);
        array.add(s4);
        array.add(s5);
        array.add(s6);
        array.add(s7);
 
        // 創建新集合
        ArrayList newArray = new ArrayList();
 
        // 遍歷舊集合,獲取得到每一個元素
        Iterator it = array.iterator();
        while (it.hasNext()) {
            Student s = (Student) it.next();
 
            // 拿這個元素到新集合去找,看有沒有
             if (!newArray.contains(s)) {
                newArray.add(s);
            }
        }
 
        // 遍歷新集合
        for (int x = 0; x < newArray.size(); x++) {
            Student s = (Student) newArray.get(x);
            System.out.println(s.getName() + "---" + s.getAge());
        }
    }

 

 

 

為什么呢?
       我們必須思考哪里會出問題?
          通過簡單的分析,我們知道問題出現在了判斷上。
          而這個判斷功能是集合自己提供的,所以我們如果想很清楚的知道它是如何判斷的,就應該去看源碼。
------有問題,查源碼

 

 

 

 

通過查源碼發現 
contains()方法的底層依賴的是equals()方法。
  而我們的學生類中沒有equals()方法,這個時候,默認使用的是它父親Object的equals()方法
  Object()的equals()默認比較的是地址值,所以,它們進去了。因為new的東西,地址值都不同。
  按照我們自己的需求,比較成員變量的值,重寫equals()即可。(在Student類中重寫)
  運用代碼自動生成即可。
 
7.請用LinkedList模擬棧數據結構的集合,並測試
 
題目的意思是:
       你自己的定義一個集合類,在這個集合類內部可以使用LinkedList模擬。
MyStack類
MySatckTest
 
8.泛型的引入,概述
有疑問,反編譯(xJad)
 
編譯不出問題,但是運行就報錯了
8.泛型概述和基本使用
回想一下,我們的數組
          String[] strArray = new String[3];
          strArray[0] = "hello";
          strArray[1] = "world";
          strArray[2] = 10;
  集合也模仿着數組的這種做法, 在創建對象的時候明確元素的數據類型。這樣就不會在有問題了。
  而這種技術被稱為:泛型。
  
  泛型:是一種把類型明確的工作推遲到創建對象或者調用方法的時候才去明確的特殊的類型。參數化類型,把類型當作參數一樣的傳遞。
  格式:
          <數據類型>
           此處的數據類型只能是引用類型。
  好處:
          A: 把運行時期的問題提前到了編譯期間
          B: 避免了強制類型轉換
          C:優化了程序設計,解決了黃色警告線
 
public static void main(String[] args) {
        // 創建
        ArrayList <String> array = new ArrayList <String>();
 
        // 添加元素
        array.add("hello");
        array.add("world");
        array.add("java");
 
        // 遍歷
        Iterator <String> it = array.iterator();
        while (it.hasNext()) {
            // ClassCastException
             // String s = (String) it.next();
             String s = it.next();
            System.out.println(s);
        }
    }
 
2.泛型在哪些地方使用呢?
看API,如果類,接口,抽象類后面跟的有<E>就說要使用泛型。 一般來說就是在集合中使用
 
以下用ArrayList存儲字符串元素,並遍歷。用泛型改進代碼
public static void main(String[] args) {
        ArrayList<String> array = new ArrayList<String>();
 
        array.add("hello");
        array.add("world");
        array.add("java");
 
        Iterator<String> it = array.iterator();
        while (it.hasNext()) {
            String s = it.next();
            System.out.println(s);
        }
        System.out.println("-----------------");
 
        for (int x = 0; x < array.size(); x++) {
             String s = array.get(x);
            System.out.println(s);
        }
    }
 
3 .JDK7的新特性--------泛型推斷
 創建集合對象
   ArrayList<Student> array = new ArrayList<Student>();//一般情況下
   JDK7的新特性: 泛型推斷
          ArrayList<Student> array = new ArrayList<>();
         但是不建議這樣使用。
        ArrayList<Student> array = new ArrayList<Student>();//還是這樣寫
 
4.泛型類:把泛型定義在類上
舉例
=============================================
ObjectTool.java
 
public class ObjectTool <T> {
    private  T obj;
 
    public  getObj() {
        return obj;
    }
 
    public void setObj( T obj) {
        this.obj = obj;
    }
}
====================================================
ObjectToolDemo.java
 
 
public class ObjectToolDemo {
    public static void main(String[] args) {
        ObjectTool <String> ot = new ObjectTool <String>();
        // ot.setObj(new Integer(27)); //這個時候編譯期間就過不去
        ot.setObj(new String("林青霞"));
        String s = ot.getObj();
        System.out.println("姓名是:" + s);
 
        ObjectTool <Integer> ot2 = new ObjectTool <Integer>();
        // ot2.setObj(new String("風清揚"));//這個時候編譯期間就過不去
        ot2.setObj(new Integer(27));
        Integer i = ot2.getObj();
        System.out.println("年齡是:" + i);
    }
}
5. 泛型方法:把泛型定義在方法上(這個時候與泛型類無關!)
原始做法
============================
ObjectTool.java
public class ObjectTool <T> {
 
    public void show( T t) {
        System.out.println(t);
    }
 }
============================
ObjectToolDemo.java
 
 ObjectTool<String> ot = new ObjectTool <String>();
        ot.show("hello");
       
        ObjectTool<Integer> ot2 = new ObjectTool <Integer>();
        ot2.show(100);
        
        ObjectTool<Boolean> ot3 = new ObjectTool <Boolean>();
       ot3.show(true);
 
        // 如果還聽得懂,那就說明泛型類是沒有問題的
        // 但是呢,誰說了我的方法一定要和類的類型的一致呢?
        // 我要是類上沒有泛型的話,方法還能不能接收任意類型的參數了呢?
 
 
 
改進(不定義泛型類,但定義了一個普通類的背后定義一個泛型方法)
ObjectTool.java
public class ObjectTool {
    public  <T> void show( T t) {
        System.out.println(t);
    }
}
 
// 定義泛型方法后 ObjectToolDemo.java
 
        ObjectTool ot = new ObjectTool();
        ot.show("hello");
        ot.show(100);
        ot.show(true);
 
6.泛型接口:把泛型定義在接口上
================================================
Inter.java(定義一個接口,而且是泛型接口)
public interface Inter<T> {
    public abstract void show(T t);
}
================================================
InterImpl.java(用一個類去實現上面的泛型接口)
//實現類在實現接口的時候
//第一種情況:已經知道該是什么類型的了(用得比較少)
 
//public class  InterImpl implements  Inter<String> {
//
//    @Override
//    public void show( String t) {
//        System.out.println(t);
//    }
// }
 
//第二種情況:還不知道是什么類型的( 這種情況最常見,推薦使用,說白了,就是用泛型類實現泛型接口)
public class  InterImpl<T> implements  Inter<T> {
 
    @Override
    public void show( T t) {
        System.out.println(t);
    }
}
=================================
InterDemo.java(測試類)
public static void main(String[] args) {
        // 第一種情況的測試
        // Inter<String> i = new InterImpl();// 只能是String,否則會報錯
        // i.show("hello");
 
        // // 第二種情況的測試
        Inter<String> i = new InterImpl<String>();
        i.show("hello");
 
        Inter<Integer> ii = new InterImpl<Integer>();
        ii.show(100);
    }
7.泛型高級之通配符
泛型高級(通配符)
 ?: 任意類型,如果沒有明確,那么就是Object以及任意的Java類了
 ? extends E:向下限定,E及 其子類
 ? super E:向上限定,E及 其父類
 
背景
class Animal {
}
 
class Dog extends Animal {
}
 
class Cat extends Animal {
}
 
泛型如果明確的寫的時候,前后必須一致

 

 

?表示任意的類型都是可以的

? extends E:向下限定,E及其子類

? super E:向上限定,E極其父類

(留意以上截圖哪些行報錯了)

 

8.JDK5的新特性----增強for
JDK5的新特性:自動拆裝箱,泛型,增強for,靜態導入,可變參數,枚舉
  
  增強for:是for循環的一種。
  
  格式:
           for(元素數據類型 變量 : 數組或者Collection集合) {
             使用變量即可,該變量就是元素
        }
  
  好處: 簡化了數組和 集合的遍歷。
 
弊端: 增強for的目標不能為null。
 *如何解決呢? 對增強for的目標先進行不為null的判斷然后再使用
==========================================
public static void main(String[] args) {
        // 定義一個 int數組
        int[] arr = { 1, 2, 3, 4, 5 };
        for (int x = 0; x < arr.length; x++) {
            System.out.println(arr[x]);
        }
        System.out.println("---------------");
        // 增強for
        for (int x : arr) {
            System.out.println(x);
        }
        System.out.println("---------------");
        // 定義一個 字符串數組
        String[] strArray = { "林青霞", "風清揚", "東方不敗", "劉意" };
        // 增強for
        for (String s : strArray) {
            System.out.println(s);
        }
        System.out.println("---------------");
        //  定義一個集合(重點留意這個遍歷的簡化)
        ArrayList<String> array = new ArrayList<String>();
        array.add("hello");
        array.add("world");
        array.add("java");
        // 增強for
        for ( String s : array) {
            System.out.println(s);
        }
        System.out.println("---------------");
    }
==============================================================
弊端: 增強for的目標不能為null。如下面所示
  List<String> list =  null;
        //  NullPointerException
        // 這個s是我們從list里面獲取出來的,在 獲取前,它肯定還要做一個 判斷
        // 說白了,這就是迭代器的功能
    //又要獲取又要判斷,所以拋出異常

 

 

//改進
         if (list != null) { //改進后,加一個判斷
            for (String s : list) {
                System.out.println(s);
            }
        }
還有一個值得注意的問題

增強for其實就是(用來替代)迭代器
迭代器遍歷集合,集合修改集合會產生 並發修改異常。換句話說,增強for就是替代了迭代器(的作用)
詳見以下這個例子
 // 增強for其實是用來替代迭代器的
        // ConcurrentModificationException
        // for (String s : array) {
        // if ("world".equals(s)) {
        // array.add("javaee");
        // }
        // }
        // System.out.println("array:" + array);

 

 
9.JDK5的新特性-----靜態導入(意義不大,能看懂即可)
 
*靜態導入的注意事項:
         A: 方法必須是靜態的
       B:如果有多個同名的靜態方法,容易不知道使用誰?這個時候要使用,必須加前綴。由此可見,意義不大,所以一般不用,但是要能看懂。
 
10.使用Eclipse快速制作方法
 
 
或者選中a + b來做方法也可以
 
11.JDK5的新特性-----可變參數
可變參數:定義方法的時候不知道該定義多少個參數
  格式:
          修飾符 返回值類型 方法名( 數據類型…  變量名){
 
          }
  
          注意:
              這里的 變量其實是一個數組
              如果一個方法有可變參數,並且有多個參數,那么,可變參數肯定是最后一個(也就是說,可以是
                method(int a, int...b),但不可以是method(int...b,int a) 。)
 
public static void main(String[] args) {
        // 2個數據求和
        int a = 10;
        int b = 20;
        int result = sum(a, b);
        System.out.println("result:" + result);
 
        // 3個數據的求和
        int c = 30;
        result = sum(a, b, c);
        System.out.println("result:" + result);
 
        // 4個數據的求和
        int d = 30;
        result = sum(a, b, c, d);
        System.out.println("result:" + result);
 
       需求:我要寫一個求和的功能,到底是幾個數據求和呢,我不太清楚,但是我知道在調用的時候我肯定就知道了
        為了解決這個問題,Java就提供了一個東西:可變參數
        result = sum(a, b, c, d, 40);
        System.out.println("result:" + result);
 
         result = sum(a, b, c, d, 40, 50);
        System.out.println("result:" + result);
    }
 
    public static int sum (int... a) {
        // System.out.println(a);
        //return 0;
 
        int s = 0;
        //在這里,其實 a是一個數組
         for(int x : a){
            s +=x;
        }
 
        return  s;
    }
通過反編譯發現,其實還是數組
 
 12.Arrays工具類的asList()方法(接收 可變參數)
 public static <T> List<T> asList( T... a):把數組轉成集合
注釋:第一個<T>表示這是一個泛型方法名叫asList
            第二個<T>表示返回值是一個泛型接口---List<T>
public static void main(String[] args) {
        // 定義一個數組
        // String[] strArray = { "hello", "world", "java" };
        // List<String> list = Arrays.asList(strArray);
 
        List<String> list = Arrays.asList("hello", "world", "java");
        // UnsupportedOperationException
        // list.add("javaee");
        // UnsupportedOperationException
        // list.remove(1);
        list.set(1, "javaee");
 
        for (String s : list) {
            System.out.println(s);
        }
    }
注意事項:
       雖然可以把數組轉成集合,但是 集合的長度不能改變
asList接收可變參數,Arrays.asList("hello", "world", "java");//可以
                               Arrays.asList("hello", "world");//也可以
 
13.一個案例:集合 嵌套存儲和遍歷元素的案例
集合的嵌套遍歷
  需求:
          我們班有學生,每一個學生是不是一個對象。所以我們可以使用一個集合表示我們班級的學生。ArrayList<Student>
         但是呢,我們旁邊是不是還有班級,每個班級是不是也是一個ArrayList<Student>。
         而我現在有多個ArrayList<Student>。也要用集合存儲,怎么辦呢?
          就是這個樣子的:ArrayList<ArrayList<Student>>
 
 
案例圖解
 
public static void main(String[] args) {
        // 創建大集合
        ArrayList<ArrayList<Student>> bigArrayList = new ArrayList<ArrayList<Student>>();
 
        // 創建第一個班級的學生集合
         ArrayList<Student> firstArrayList = new ArrayList<Student>();
        // 創建學生
        Student s1 = new Student("唐僧", 30);
        Student s2 = new Student("孫悟空", 29);
        Student s3 = new Student("豬八戒", 28);
        Student s4 = new Student("沙僧", 27);
        Student s5 = new Student("白龍馬", 26);
        // 學生進班
        firstArrayList.add(s1);
        firstArrayList.add(s2);
        firstArrayList.add(s3);
        firstArrayList.add(s4);
        firstArrayList.add(s5);
        // 把第一個班級存儲到學生系統中
         bigArrayList.add(firstArrayList);
 
        // 創建第二個班級的學生集合
         ArrayList<Student> secondArrayList = new ArrayList<Student>();
        // 創建學生
        Student s11 = new Student("諸葛亮", 30);
        Student s22 = new Student("司馬懿", 28);
        Student s33 = new Student("周瑜", 26);
        // 學生進班
        secondArrayList.add(s11);
        secondArrayList.add(s22);
        secondArrayList.add(s33);
        // 把第二個班級存儲到學生系統中
         bigArrayList.add(secondArrayList);
 
        // 創建第三個班級的學生集合
         ArrayList<Student> thirdArrayList = new ArrayList<Student>();
        // 創建學生
        Student s111 = new Student("宋江", 40);
        Student s222 = new Student("吳用", 35);
        Student s333 = new Student("高俅", 30);
        Student s444 = new Student("李師師", 22);
        // 學生進班
        thirdArrayList.add(s111);
        thirdArrayList.add(s222);
        thirdArrayList.add(s333);
        thirdArrayList.add(s444);
        // 把第三個班級存儲到學生系統中
         bigArrayList.add(thirdArrayList);
 
        // 遍歷集合
         for (ArrayList<Student> array : bigArrayList) {
             for (Student s : array) {
                System.out.println(s.getName() + "---" + s.getAge());
            }
        }
    }
 
14.第二個案例
 
獲取10個1-20之間的隨機數,要求不能重復
 
用數組實現, 但是數組的長度是固定的,長度不好確定
  所以我們使用集合實現
  
  分析:
          A:創建產生隨機數的對象
         B:創建一個存儲隨機數的集合。
          C:定義一個統計變量。從0開始。
          D:判斷統計遍歷是否小於10
              是:先產生一個隨機數,判斷該隨機數在集合中是否存在。
                      如果不存在:就添加,統計變量++。
                      如果存在:就不搭理它。
              否:不搭理它
          E:遍歷集合
 
 
實現代碼參考
public static void main(String[] args) {
         // 創建產生隨機數的對象
        Random r = new Random();
 
        // 創建一個存儲隨機數的集合。
        ArrayList<Integer> array = new ArrayList<Integer>();
 
        // 定義一個統計變量。從0開始。
        int count = 0;
 
        // 判斷統計遍歷是否小於10
        while (count < 10) {
            //先產生一個隨機數
            int number =  r.nextInt(20) + 1;
 
            //判斷該隨機數在集合中是否存在。
            if(!array. contains(number)){
                //如果不存在:就添加,統計變量++。
                array.add(number);
                count++;
            }
        }
 
        //遍歷集合
        for(Integer i : array){
            System.out.println(i);
        }
    }
 
15.案例3
 
  需求:鍵盤錄入多個數據, 以0結束,要求在控制台輸出這多個數據中的 最大值
  
 分析:
          A:創建鍵盤錄入數據對象
          B:鍵盤錄入多個數據,我們不知道多少個,所以用集合存儲
          C:以0結束,這個簡單,只要鍵盤錄入的數據是0,我就不繼續錄入數據了
          D:把集合轉成數組
          E:對數組排序
          F:獲取該數組中的最大索引的值
 
示例代碼
public static void main(String[] args) {
        // 創建鍵盤錄入數據對象
        Scanner sc = new Scanner(System.in);
 
        // 鍵盤錄入多個數據,我們不知道多少個,所以用集合存儲
        ArrayList<Integer> array = new ArrayList<Integer>();
 
        // 以0結束,這個簡單,只要鍵盤錄入的數據是0,我就不繼續錄入數據了
        while (true) {
            System.out.println("請輸入數據:");
            int number = sc.nextInt();
            if (number != 0) {
                array.add(number);
            } else {
                break;
            }
        }
 
        // 把集合轉成數組
        // public <T> T[] toArray(T[] a)
        Integer[] i = new Integer[array.size()];
        // Integer[] ii = array.toArray(i);
        array.toArray(i);
        // System.out.println(i);
        // System.out.println(ii);
 
        // 對數組排序
        // public static void sort(Object[] a)
        Arrays.sort(i);
 
        // 獲取該數組中的最大索引的值
        System.out.println("數組是:" + arrayToString(i) + "最大值是:"
                + i[i.length - 1]);
    }
 
    public static  String  arrayToString(Integer[] i) {
         StringBuilder sb = new StringBuilder();
 
        sb.append("[");
        for (int x = 0; x < i.length; x++) {
            if (x == i.length - 1) {
                sb.append(i[x]);
            } else {
                sb.append(i[x]).append(", ");
            }
        }
        sb.append("]");
 
        return  sb.toString();
    }
幾個注意或者有疑問的地方
 
 
 
 
day17
 
1.(ArrayList集合的toString()方法源碼解析
解析
代碼:
    Collection c = new ArrayList();
    c.add("hello");
    c.add("world");
    c.add("java");
 
    System.out.println(c);
 
為什么c輸出的不是地址值呢?
    A:Collection c = new ArrayList();
        這是多態,所以輸出c的toString()方法,其實是輸出ArrayList的toString()
    B:看ArrayList的toString()
        而我們在ArrayList里面卻沒有發現toString()。
        以后遇到這種情況,也不要擔心,你認為有,它卻沒有,就應該去它父親里面看看。
    C:toString()的方法源碼
 
        public String toString() {
            Iterator<E> it = iterator(); //集合本身調用迭代器方法,得到集合迭代器
            if (! it.hasNext())
                return "[]";
 
            StringBuilder sb = new StringBuilder();
            sb.append('[');
            for (;;) {
                E e = it.next(); //e=hello,world,java
                sb.append(e == this ? "(this Collection)" : e);
                if (! it.hasNext())
                    //[hello, world, java]
                    return sb.append(']').toString();
                sb.append(',').append(' ');
            }
        }
 
2.用戶登錄注冊案例
 
part1:分析圖解
part2:用戶登錄注冊案例分析
需求:用戶登錄注冊案例。
 
按照如下的操作,可以讓我們更符號面向對象思想
    A:有哪些類呢?
    B:每個類有哪些東西呢?
    C:類與類之間的關系是什么呢?
 
分析:
    A:有哪些類呢?
        用戶類
        測試類
    B:每個類有哪些東西呢?
        用戶類:
            成員變量:用戶名,密碼
            構造方法:無參構造
            成員方法:getXxx()/setXxx()
                       登錄,注冊
 
             假如用戶類的內容比較對,將來維護起來就比較麻煩,為了更清晰的分類,我們就把用戶又划分成了兩類
                用戶基本描述類
                    成員變量:用戶名,密碼
                    構造方法:無參構造
                    成員方法:getXxx()/setXxx()
                用戶操作類
                    登錄,注冊
        測試類:
            main方法。
    C:類與類之間的關系是什么呢?
        在測試類中創建用戶操作類和用戶基本描述類的對象,並使用其功能。
 
分包:
    A:功能划分
    B:模塊划分
    C:先按模塊划分,再按功能划分
 
今天我們選擇按照功能划分:
    用戶基本描述類包 cn.itcast. pojo
    用戶操作接口 cn.itcast. dao
    用戶操作類包 cn.itcast .dao.impl
         今天是集合實現,過幾天是IO實現,再過幾天是GUI實現,就業班我們就是數據庫實現
    用戶測試類 cn.itcast.test
 
part3:用戶登錄注冊案例用戶 基本描述類用戶操作接口的實現
  新建一個包  cn.itcast.pojo
=============分割線==============
package cn.itcast.pojo;
 
/**
 * 這是用戶基本描述類
 * 
 * @author 風清揚
 * @version V1.0
 * 
 */
public class User {
    // 用戶名
    private String username;
    // 密碼
    private String password;
 
    public User() {
    }
 
    public String getUsername() {
        return username;
    }
 
    public void setUsername(String username) {
        this.username = username;
    }
 
    public String getPassword() {
        return password;
    }
 
    public void setPassword(String password) {
        this.password = password;
    }
}
 
============分割線==================
再新建一個包 cn.itcast.dao
 
========分割線===============
package cn.itcast.dao;
 
import cn.itcast.pojo.User;
 
/**
 *  這是針對用戶進行操作的接口
 * 
 * @author 風清揚
 * @version V1.0
 * 
 */
public interface UserDao {
    /**
     * 這是用戶登錄功能
     * 
     * @param username
     *            用戶名
     * @param password
     *            密碼
     * @return 返回登錄是否成功
     */
    public abstract boolean isLogin(String username, String password);
 
    /**
     * 這是用戶注冊功能
     * 
     * @param user
     *            要注冊的用戶信息
     */
    public abstract void regist(User user);
}
========分割線==========================
兩個注意問題
 
再新建一個包 cn.itcast.dao.impl  
UserDaoImpl.java
============分割線=================
package cn.itcast.dao.impl;
 
import java.util.ArrayList;
 
import cn.itcast.dao.UserDao;
import cn.itcast.pojo.User;
 
/**
 * 這是用戶操作的具體實現類(集合版)
 * 
 * @author 風清揚
 * @version V1.0
 * 
 */
public class UserDaoImpl implements UserDao {
     // 為了讓多個方法能夠使用同一個集合,就把集合定義為成員變量
    // 為了不讓外人看到,用private
    // 為了讓多個對象共享同一個成員變量,用static
    private static ArrayList<User> array = new ArrayList<User>();
 
    @Override
    public boolean isLogin(String username, String password) {
        // 遍歷集合,獲取每一個用戶,並判斷該用戶的用戶名和密碼是否和傳遞過來的匹配
        boolean flag = false;
 
        for (User u : array) {
            if (u.getUsername().equals(username)
                    && u.getPassword().equals(password)) {
                flag = true;
                break;
            }
        }
 
        return flag;
    }
 
    @Override
    public void regist(User user) {
        // 把用戶信息存儲集合
        // ArrayList<User> array = new ArrayList<User>();
        array.add(user);
    }
}
 
===========分割線================
 
再新建一個包 cn.itcast.test
UserTest.java

 

==========分割線====================
package cn.itcast.test;
 
import java.util.Scanner;
 
import cn.itcast.dao.UserDao;
import cn.itcast.dao.impl.UserDaoImpl;
import cn.itcast.game.GuessNumber;
import cn.itcast.pojo.User;
 
/**
 * 用戶測試類
 * 
 * @author 風清揚
 * @version V1.0
 * 
 *           新增加了兩個小問題 A:多個對象共享同一個成員變量,用靜態
 *          B:循環里面如果有switch,並且在switch里面有break,那么結束的不是循環,而是switch語句
 * 
 */
public class UserTest {
    public static void main(String[] args) {
        // 為了能夠回來
        while (true) {
            // 歡迎界面,給出選擇項
            System.out.println("--------------歡迎光臨--------------");
            System.out.println("1 登錄");
            System.out.println("2 注冊");
            System.out.println("3 退出");
            System.out.println("請輸入你的選擇:");
            // 鍵盤錄入選擇,根據選擇做不同的操作
            Scanner sc = new Scanner(System.in);
            // 為了后面的錄入信息的方便,我所有的數據錄入全部用字符接收
            String choiceString = sc.nextLine();
 
            // switch語句的多個地方要使用,我就定義到外面
             UserDao ud = new UserDaoImpl();
 
            // 經過簡單的思考,我選擇了switch,而且是 JDK1.7以及以后才能用,因為switch接收了字符串
             switch (choiceString) {
            case "1":
                // 登錄界面,請輸入用戶名和密碼
                System.out.println("--------------登錄界面--------------");
                System.out.println("請輸入用戶名:");
                String username = sc.nextLine();
                System.out.println("請輸入密碼:");
                String password = sc.nextLine();
 
                // 調用登錄功能
                // UserDao ud = new UserDaomImpl();
 
                 boolean flag = ud.isLogin(username, password);
                if (flag) {
                    System.out.println("登錄成功,可以開始玩游戲了");
 
                    System.out.println("你玩嗎?y/n");
                    while (true) {
                        String resultString = sc.nextLine();
                        if (resultString.equalsIgnoreCase("y")) {
                            // 玩游戲
                            GuessNumber.start();
                            System.out.println("你還玩嗎?y/n");
                        } else {
                            break;
                        }
                    }
                    System.out.println("謝謝使用,歡迎下次再來");
                     System.exit(0);
                     // break; //這里寫break,結束的是switch
                } else {
                    System.out.println("用戶名或者密碼有誤,登錄失敗");
                }
                break;
            case "2":
                // 歡迎界面,請輸入用戶名和密碼
                System.out.println("--------------注冊界面--------------");
                System.out.println("請輸入用戶名:");
                String newUsername = sc.nextLine();
                System.out.println("請輸入密碼:");
                String newPassword = sc.nextLine();
 
                // 把用戶名和密碼封裝到一個對象中
                 User user = new User();
                user.setUsername(newUsername);
                user.setPassword(newPassword);
 
                // 調用注冊功能
                // 多態
                // UserDao ud = new UserDaoImpl();
                // 具體類使用
                // UserDaoImpl udi = new UserDaoImpl();
 
                ud.regist(user);
                System.out.println("注冊成功");
                break;
            case "3":
            default:
                System.out.println("謝謝使用,歡迎下次再來");
                 System.exit(0);
                //break;
            }
        }
    }
}
===============分割線===================
3.Set集合概述及特點
Collection
 *         |--List
 *             有序(存儲順序和取出順序一致),可重復
 *         |--Set
 *              無序(存儲順序和取出順序不一致), 唯一
 * 
 * HashSet:它不保證 set 的迭代順序;特別是它不保證該順序恆久不變。
 * 注意:雖然Set集合的元素無序,但是,作為集合來說,它肯定有它自己的存儲順序,
 * 而你的順序恰好和它的存儲順序一致,這代表不了有序,你可以多存儲一些數據,就能看到效果。
 
4.HashSet集合的add()方法的 源碼以及解析
 HashSet:存儲字符串並遍歷
 * 問題:為什么 存儲字符串的時候, 字符串內容相同的只存儲了一個呢?
 
interface Collection {
    ...
}
 
interface Set extends Collection {
    ...
}
 
class HashSet implements Set {
    private static final Object PRESENT = new Object();
    private transient HashMap<E,Object> map;
 
    public HashSet() {
        map = new HashMap<>();
    }
 
    public boolean add(E e) { //e=hello,world
        return map.put(e, PRESENT)==null;
    }
}
 
class HashMap implements Map {
    public V put(K key, V value) { //key=e=hello,world
 
        //看哈希表是否為空,如果空,就開辟空間
        if (table == EMPTY_TABLE) {
            inflateTable(threshold);
        }
 
        //判斷對象是否為null
        if (key == null)
            return putForNullKey(value);
 
         int hash = hash(key); //和對象的hashCode()方法相關
 
        //在哈希表中查找hash值
        int i = indexFor(hash, table.length);
         for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            //這次的e其實是第一次的world
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
                //走這里其實是沒有添加元素
            }
        }
 
        modCount++;
        addEntry(hash, key, value, i); //把元素添加
        return null;
    }
 
    transient int hashSeed = 0;
 
    final int hash(Object k) { //k=key=e=hello,
        int h = hashSeed;
        if (0 != h && k instanceof String) {
            return sun.misc.Hashing.stringHash32((String) k);
        }
 
        h ^= k.hashCode(); //這里調用的是對象的hashCode()方法
 
        // This function ensures that hashCodes that differ only by
        // constant multiples at each bit position have a bounded
        // number of collisions (approximately 8 at default load factor).
        h ^= (h >>> 20) ^ (h >>> 12);
        return h ^ (h >>> 7) ^ (h >>> 4);
    }
}
 
 
hs.add("hello");
hs.add("world");
hs.add("java");
hs.add("world");
 
總結:通過查看add方法的源碼,我們知道這個方法底層依賴 兩個方法:hashCode()和equals()。
 * 步驟:
 *         首先比較哈希值
 *         如果相同,繼續走,比較地址值或者走equals()
 *         如果不同,就直接添加到集合中    
 * 按照方法的步驟來說:    
 *         先看hashCode()值是否相同
 *             相同:繼續走equals()方法
 *                 返回true:    說明元素重復,就不添加
 *                 返回false:說明元素不重復,就添加到集合
 *             不同:就直接把元素添加到集合
 *  如果類沒有重寫這兩個方法,默認使用的Object()。一般來說不會相同。
 *  而String類重寫了hashCode()和equals()方法,所以,它就可以把內容相同的字符串去掉。只留下一個。
 
以下兩個重寫都在學生類Student類中修改
重寫hashCode方法

      重寫equals方法

需要手動重寫的代碼如下
 @Override
         public int hashCode() {
         // return 0;
         //  因為成員變量值影響了哈希值,所以我們把成員變量值相加即可
         // return this.name.hashCode() + this.age;
         // 看下面
         // s1:name.hashCode()=40,age=30
         // s2:name.hashCode()=20,age=50
         // 盡可能的 區分,我們可以把它們乘以一些整數(乘上整數 擴大分差把細微差別放大避免偶爾誤差)
         return this.name.hashCode()  + this.age  * 15;
         }
 
         @Override
         public boolean equals(Object obj) {
         //  System.out.println(this + "---" + obj);//測試比較順序以及比較次數的代碼,測試后注釋掉
         if (this == obj) {
         return true;
         }
 
         if (!(obj  instanceof Student)) {
         return false;
         }
 
         Student s = (Student) obj;
         return this.name.equals(s.name) && this.age == s.age;
         }
@Override
         public String toString() {
         return "Student [name=" + name + ", age=" + age + "]";
         }
優化測試截圖(優化前hashCode默認返回值是0.也就是所有的元素哈希值都一樣)
優化前,比較次數比較大

 優化后(哈希值不再一樣,通過哈希值與成員變量相加來重寫hashCode方法避免不必要的比較)

但實際上,一般不自己想寫這么麻煩,可以用代碼自動生成功能來實現

 

 

以后解決HashSet 存儲自定義對象時元素不唯一問題就可以用重寫hashCode()方法和equals()方法解決

 

5.HashSet集合存儲自定義對象並遍歷
如果對象的成員變量值相同即為同一個對象
 
注意了:
 *         你使用的是HashSet集合,這個集合的底層是哈希表結構。
 *         而哈希表結構底層依賴:hashCode()和equals()方法。
 *         如果你認為對象的成員變量值相同即為同一個對象的話,你就應該重寫這兩個方法。
 *         如何重寫呢?不同擔心,自動生成即可。
 
import java.util.HashSet;
 
public class DogDemo {
    public static void main(String[] args) {
        HashSet<Dog> hs = new HashSet<Dog>();
 
        Dog d1 = new Dog("網", 27, "綠色", '男');
        Dog d2 = new Dog("隨", 27, "綠色", '男');
        Dog d3 = new Dog("王", 27, "綠色", '男');
        Dog d4 = new Dog("網", 27, "綠色", '男');
        Dog d5 = new Dog("網", 27, "綠色", '女');
 
        hs.add(d1);
        hs.add(d2);
        hs.add(d3);
        hs.add(d4);
        hs.add(d5);
 
        for (Dog d : hs) {
            System.out.println(d.getName() + "---" + d.getAge() + "---" + d.getColor() + "---" + d.getSex());
        }
 
    }
}
 
Dog類
public class Dog {
    private String name;
    private int age;
    private String color;
    private char sex;
 
    public Dog() {
        super();
        // TODO Auto-generated constructor stub
    }
 
    public Dog(String name, int age, String color, char sex) {
        super();
        this.name = name;
        this.age = age;
        this.color = color;
        this.sex = sex;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public int getAge() {
        return age;
    }
 
    public void setAge(int age) {
        this.age = age;
    }
 
    public String getColor() {
        return color;
    }
 
    public void setColor(String color) {
        this.color = color;
    }
 
    public char getSex() {
        return sex;
    }
 
    public void setSex(char sex) {
        this.sex = sex;
    }
 
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((color == null) ? 0 : color.hashCode());
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        result = prime * result + sex;
        return result;
    }
 
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Dog other = (Dog) obj;
        if (age != other.age)
            return false;
        if (color == null) {
            if (other.color != null)
                return false;
        } else if (!color.equals(other.color))
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        if (sex != other.sex)
            return false;
        return true;
    }
 
}
6.TreeSet
TreeSet:能夠對元素按照某種規則進行排序。
排序有兩種方式
 * A:自然排序
 * B:比較器排序
 * 
 * TreeSet集合的特點:排序和唯一
 * 
 * 通過觀察TreeSet的add()方法,我們知道最終要看TreeMap的put()方法。
 
7. TreeSet保證元素排序的源碼解析
interface Collection {...}
 
interface Set extends Collection {...}
 
interface NavigableMap {
 
}
 
class TreeMap implements NavigableMap {
     public V put(K key, V value) {
        Entry<K,V> t = root;
        if (t == null) {
            compare(key, key); // type (and possibly null) check
 
            root = new Entry<>(key, value, null);
            size = 1;
            modCount++;
            return null;
        }
        int cmp;
        Entry<K,V> parent;
        // split comparator and comparable paths
         Comparator<? super K> cpr = comparator;
        if (cpr != null) {
            do {
                parent = t;
                cmp = cpr.compare(key, t.key);
                if (cmp < 0)
                    t = t.left;
                else if (cmp > 0)
                    t = t.right;
                else
                    return t.setValue(value);
            } while (t != null);
        }
        else {
            if (key == null)
                throw new NullPointerException();
             Comparable<? super K> k = (Comparable<? super K>) key;
            do {
                parent = t;
                cmp = k. compareTo(t.key);
                if (cmp < 0)
                    t = t.left;
                else if (cmp > 0)
                    t = t.right;
                else
                    return t.setValue(value);
            } while (t != null);
        }
        Entry<K,V> e = new Entry<>(key, value, parent);
        if (cmp < 0)
            parent.left = e;
        else
            parent.right = e;
        fixAfterInsertion(e);
        size++;
        modCount++;
        return null;
    }
}
 
class TreeSet implements Set {
    private transient NavigableMap<E,Object> m;
 
    public TreeSet() {
         this(new TreeMap<E,Object>());
    }
 
    public boolean add(E e) {
        return m.put(e, PRESENT)==null;
    }
}
 
真正的比較是 依賴於元素的compareTo()方法,而這個方法是 定義在 Comparable里面的。
所以,你要想重寫該方法,就必須是先  實現Comparable接口。這個接口表示的就是 自然排序
 
附:TreeSet保證元素唯一性和自然排序的原理和圖解
7.TreeSet存儲自定義對象並遍歷練習1
 
下面貼代碼
TreeSetDemo2.java
===============分割線===================
import java.util.TreeSet;
 
/*
 * TreeSet存儲自定義對象並保證排序和唯一。
 * 
 * A:你沒有告訴我們怎么排序
 *         自然排序,按照年齡從小到大排序
 * B:元素什么情況算唯一你也沒告訴我
 *         成員變量值都相同即為同一個元素
 */
public class TreeSetDemo2 {
    public static void main(String[] args) {
        // 創建集合對象
        TreeSet<Student> ts = new TreeSet<Student>();
 
        // 創建元素
        Student s1 = new Student("linqingxia", 27);
        Student s2 = new Student("zhangguorong", 29);
        Student s3 = new Student("wanglihong", 23);
        Student s4 = new Student("linqingxia", 27);
        Student s5 = new Student("liushishi", 22);
        Student s6 = new Student("wuqilong", 40);
        Student s7 = new Student("fengqingy", 22);
 
        // 添加元素
        ts.add(s1);
        ts.add(s2);
        ts.add(s3);
        ts.add(s4);
        ts.add(s5);
        ts.add(s6);
        ts.add(s7);
 
        // 遍歷
        for (Student s : ts) {
            System.out.println(s.getName() + "---" + s.getAge());
        }
    }
}
==============分割線==============
Student類
Student.java
==============分割線==============
 
/*
 *  如果一個類的元素要想能夠進行自然排序,就必須實現自然排序接口
 */
public class Student  implements Comparable<Student> {
    private String name;
    private int age;
 
    public Student() {
        super();
    }
 
    public Student(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public int getAge() {
        return age;
    }
 
    public void setAge(int age) {
        this.age = age;
    }
 
    @Override
    public int compareTo(Student s) {
        // return 0;
        // return 1;
        // return -1;
 
        // 這里返回什么,其實應該根據我的排序規則來做
        // 按照年齡排序,主要條件
        int num = this.age - s.age;
        // 次要條件
        //  年齡相同的時候,還得去看姓名是否也相同
        // 如果年齡和姓名都相同,才是同一個元素
        //String 默認已經實現了Comparable接口,所以可以大膽用compareTo方法
        int num2 = num == 0 ? this.name. compareTo(s.name) : num;
        return num2;
    }
}
 
下面是以上代碼的解析。
 
附:A:首先解析以下這行代碼
     int num2 = num == 0 ?  this.name. compareTo( s.name) : num;
解:這行語句是三目運算符,意思是先比較主要條件---年齡,num為年齡比較產生的返回值,如果是零就不插入二叉樹(TreeSet)中(通過比較發現年齡重復就不添加),如果此時直接返回num的話會造成Student對象的意外丟失(例如年齡相同但實際上姓名不相同的學生對象),
 
因此為了解決這個問題,新添加了num2,考慮多了次要條件姓名,如果年齡相同的同時姓名也相同就返回num2的值0,代表不添加元素到二叉樹中。
 
B:String 默認已經實現了Comparable接口
 
C:為什么要在自定義類Student中實現Comparable接口呢?(implements Comparable<T>)
如果不實現這個接口,運行如下
 
查API
 
由上圖可知:實現這個借口 是為了進行自然排序。Student類默認並沒有實現Comparable接口
 
Comparable接口 只有一個compareTo方法,實現接口時需要重寫這個方法
 
8.TreeSet存儲自定義對象並遍歷練習2
先貼代碼
==============分割線=======================
import java.util.TreeSet;
 
/*
 * 需求:請按照姓名的長度排序
 */
public class TreeSetDemo {
    public static void main(String[] args) {
        // 創建集合對象
        TreeSet<Student> ts = new TreeSet<Student>();
 
        // 創建元素
         Student s1 = new Student("linqingxia", 27);
        Student s2 = new Student("zhangguorong", 29);
         Student s3 = new Student("wanglihong", 23);//s1與s3名字長度相同
         Student s4 = new Student("linqingxia", 27);
        Student s5 = new Student("liushishi", 22);
        Student s6 = new Student("wuqilong", 40);
        Student s7 = new Student("fengqingy", 22);
         Student s8 = new Student("linqingxia", 29);
 
        // 添加元素
        ts.add(s1);
        ts.add(s2);
        ts.add(s3);
        ts.add(s4);
        ts.add(s5);
        ts.add(s6);
        ts.add(s7);
        ts.add(s8);
 
        // 遍歷
        for (Student s : ts) {
            System.out.println(s.getName() + "---" + s.getAge());
        }
    }
}
 
=================分割線=====================
Student類
 
/*
 *  如果一個類的元素要想能夠進行自然排序,就必須實現自然排序接口
 */
public class Student implements Comparable<Student> {
    private String name;
    private int age;
 
    public Student() {
        super();
    }
 
    public Student(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public int getAge() {
        return age;
    }
 
    public void setAge(int age) {
        this.age = age;
    }
 
     @Override
    public int compareTo(Student s) {
        // 主要條件 姓名的長度
        int num = this.name.length() - s.name.length();
        // 姓名的長度相同,不代表姓名的內容相同
        int num2 = num == 0 ? this.name.compareTo(s.name) : num;
        // 姓名的長度和內容相同,不代表年齡相同,所以還得繼續判斷年齡
        int num3 = num2 == 0 ? this.age - s.age : num2;
        return num3;
    }
}
 
留意看上面stuedent類中的compareTo方法,雖然需求中只說明了按照姓名的長度排序,但是 隱含的比較,隱含的條件(如姓名的內容,年齡是否相同)卻是不能忽略的!
 
9.TreeSet保證元素唯一性和 比較器排序的原理及代碼實現
 
TreeSet集合保證元素排序和唯一性的原理
 *  唯一性:是根據比較的返回是否是0來決定。
 * 排序:
 *         A:自然排序(元素具備比較性)
 *             讓元素所屬的類實現自然排序接口 Comparable
 *         B: 比較器排序(集合具備比較性)
 *             讓集合的構造方法接收一個 比較器接口的子類對象 Comparator
 
查API-----TreeSet  比較器排序  帶參構造方法

 

 

首先,慣例新建一個TreeSetDemo
=========分割線==========
import java.util.Comparator;
import java.util.TreeSet;
 
/*
 * 需求:請按照姓名的長度排序
 */
public class TreeSetDemo {
    public static void main(String[] args) {
        // 創建集合對象
        // TreeSet<Student> ts = new TreeSet<Student>(); //自然排序
         // public TreeSet(Comparator comparator) //比較器排序
         TreeSet<Student> ts = new TreeSet<Student>(new MyComparator());
 
        // 創建元素
        Student s1 = new Student("linqingxia", 27);
        Student s2 = new Student("zhangguorong", 29);
        Student s3 = new Student("wanglihong", 23);
        Student s4 = new Student("linqingxia", 27);
        Student s5 = new Student("liushishi", 22);
        Student s6 = new Student("wuqilong", 40);
        Student s7 = new Student("fengqingy", 22);
        Student s8 = new Student("linqingxia", 29);
 
        // 添加元素
        ts.add(s1);
        ts.add(s2);
        ts.add(s3);
        ts.add(s4);
        ts.add(s5);
        ts.add(s6);
        ts.add(s7);
        ts.add(s8);
 
        // 遍歷
        for (Student s : ts) {
            System.out.println(s.getName() + "---" + s.getAge());
        }
    }
}
===========分割線===============
在同一個包下定義一個Student類
================分割線======================
public class Student {
    private String name;
    private int age;
 
    public Student() {
        super();
    }
 
    public Student(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public int getAge() {
        return age;
    }
 
    public void setAge(int age) {
        this.age = age;
    }
}
 
================分割線================
 
最后,同一個包下定義一個MyComparator類

 

 

import java.util.Comparator;
 
public class MyComparator  implements Comparator<Student> {
 
    @Override
    public int  compare(Student s1, Student s2) {
        // int num = this.name.length() - s.name.length();
        // this -- s1
        // s -- s2
        // 姓名長度
        int num =  s1.getName().length() - s2. getName().length();
        // 姓名內容
        int num2 = num == 0 ? s1. getName().compareTo(s2. getName()) : num;
        // 年齡
        int num3 = num2 == 0 ? s1. getAge() - s2. getAge() : num2;
        return num3;
    }
 
}
 
以下為一些解析說明
A:上面專門定義了一個類MyComparator,其實也可以省略這一個類,直接在TreeSetDemo測試類中定義
一個匿名內部類
如下
TreeSetDemo.java
=================分割線========================
import java.util.Comparator;
import java.util.TreeSet;
 
 
public class TreeSetDemo {
    public static void main(String[] args) {
        // 創建集合對象
        // TreeSet<Student> ts = new TreeSet<Student>(); //自然排序
        // public TreeSet( Comparator comparator) //比較器排序
        // TreeSet<Student> ts = new TreeSet<Student>( new MyComparator());
 
        / / 如果一個方法的參數是接口,那么真正要的是接口的實現類的對象
        // 而匿名內部類就可以實現這個東西
        TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {
            @Override
            public int compare(Student s1, Student s2) {
                // 姓名長度
                int num = s1.getName().length() - s2.getName().length();
                // 姓名內容
                int num2 = num == 0 ? s1.getName().compareTo(s2.getName())
                        : num;
                // 年齡
                int num3 = num2 == 0 ? s1.getAge() - s2.getAge() : num2;
                return num3;
            }
        });
 
        // 創建元素
        Student s1 = new Student("linqingxia", 27);
        Student s2 = new Student("zhangguorong", 29);
        Student s3 = new Student("wanglihong", 23);
        Student s4 = new Student("linqingxia", 27);
        Student s5 = new Student("liushishi", 22);
        Student s6 = new Student("wuqilong", 40);
        Student s7 = new Student("fengqingy", 22);
        Student s8 = new Student("linqingxia", 29);
 
        // 添加元素
        ts.add(s1);
        ts.add(s2);
        ts.add(s3);
        ts.add(s4);
        ts.add(s5);
        ts.add(s6);
        ts.add(s7);
        ts.add(s8);
 
        // 遍歷
        for (Student s : ts) {
            System.out.println(s.getName() + "---" + s.getAge());
        }
    }
}
 
===============分割線=======================
B:在MyComparator類 中getName(),getAge()與this.name 和this.age 問題
 
外部類不能訪問private修飾的成員變量
C:注意兩個不同的接口以及它們的方法
 
接口 Comparable======方法compareTo
接口 Comparator ==== 方法compare
* TreeSet集合保證元素排序和唯一性的原理
 * 唯一性:是根據比較的 返回是否是0來決定。
 * 排序:
 *         A: 自然排序( 元素具備比較性)(Student類實現比較接口)
 *             讓元素所屬的類實現自然排序接口 Comparable
 *         B: 比較器排序( 集合具備比較性)(也就是說,Student類不需要實現任何接口)
 *             讓集合的構造方法接收一個比較器接口的子類對象 Comparator
 
 
10.一個案例----編寫一個程序,獲取 10個1至20的隨機數,要求 隨機數不能重復
 
import java.util.HashSet;
import java.util.Random;
 
/*
 * 編寫一個程序,獲取10個1至20的隨機數,要求隨機數不能重復。
 * 
 * 分析:
 *         A:創建隨機數對象
 *         B:創建一個HashSet集合
 *         C:判斷集合的長度是不是小於10
 *             是:就創建一個隨機數添加
 *             否:不搭理它
 *         D:遍歷HashSet集合
 */
public class HashSetDemo {
    public static void main(String[] args) {
        // 創建隨機數對象
         Random r = new Random();
 
        // 創建一個Set集合
        HashSet<Integer> ts = new HashSet<Integer>();//Integer默認已經實現了比較接口 Comparable
 
        // 判斷集合的長度是不是小於10
        while (ts.size() < 10) {
            int num = r.nextInt(20) + 1;
            ts.add(num);
        }
 
        // 遍歷Set集合
        for (Integer i : ts) {
            System.out.println(i);
        }
    }
}
 
 
11.一個案例----鍵盤錄入5個學生信息(姓名,語文成績,數學成績,英語成績),按照總分從高到低輸出到控制台
TreeSetDemo .java
import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;
 
/*
 * 鍵盤錄入5個學生信息(姓名,語文成績,數學成績,英語成績),按照總分從高到低輸出到控制台
 * 
 * 分析:
 *         A:定義學生類
 *         B:創建一個TreeSet集合
 *         C:總分從高到底如何實現呢?        
 *         D:鍵盤錄入5個學生信息
 *         E:遍歷TreeSet集合
 */
public class TreeSetDemo {
    public static void main(String[] args) {
        // 創建一個TreeSet集合
        TreeSet<Student> ts = new TreeSet<Student> (new Comparator<Student>() {
            @Override
            public int  compare(Student s1, Student s2) {
                 // 總分從高到低
                int num = s 2.getSum() -  s1.getSum();//s1與s2的位置已互換,因為成績從高到低而不是默認的從低到高
                // 總分相同的不一定語文相同
                int num2 = num == 0 ? s1.getChinese() - s2.getChinese() : num;
                // 總分相同的不一定數序相同
                int num3 = num2 == 0 ? s1.getMath() - s2.getMath() : num2;
                // 總分相同的不一定英語相同
                int num4 = num3 == 0 ? s1.getEnglish() - s2.getEnglish() : num3;
                // 姓名還不一定相同呢
                int num5 = num4 == 0 ? s1.getName().compareTo(s2.getName())
                        : num4;
                return num5;
            }
        });
 
        System.out.println("學生信息錄入開始");
        // 鍵盤錄入5個學生信息
        for (int x = 1; x <= 5; x++) {
            Scanner sc = new Scanner(System.in);
            System.out.println("請輸入第" + x + "個學生的姓名:");
            String name = sc.nextLine();
            System.out.println("請輸入第" + x + "個學生的語文成績:");
            String chineseString = sc.nextLine();
            System.out.println("請輸入第" + x + "個學生的數學成績:");
            String mathString = sc.nextLine();
            System.out.println("請輸入第" + x + "個學生的英語成績:");
            String englishString = sc.nextLine();
 
            // 把數據封裝到學生對象中
            Student s = new Student();
            s. setName(name);
            s .setChinese (Integer.parseInt(chineseString));
            s. setMath(Integer. parseInt(mathString));
            s. setEnglish(Integer. parseInt(englishString));
 
            // 把學生對象添加到集合
             ts.add(s);
        }
        System.out.println("學生信息錄入完畢");
 
        System.out.println("學習信息從高到低排序如下:");
        System.out.println("姓名\t語文成績\t數學成績\t英語成績");
        // 遍歷集合
        for (Student s : ts) {
            System.out.println(s.getName() +  "\t" + s.getChinese() +  "\t"
                    + s.getMath() +  "\t" + s.getEnglish());
        }
    }
}
 
===================================================
Student類
 
public class Student {
    // 姓名
    private String name;
    // 語文成績
    private int chinese;
    // 數學成績
    private int math;
    // 英語成績
    private int english;
 
    public Student(String name, int chinese, int math, int english) {
        super();
        this.name = name;
        this.chinese = chinese;
        this.math = math;
        this.english = english;
    }
 
    public Student() {
        super();
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public int getChinese() {
        return chinese;
    }
 
    public void setChinese(int chinese) {
        this.chinese = chinese;
    }
 
    public int getMath() {
        return math;
    }
 
    public void setMath(int math) {
        this.math = math;
    }
 
    public int getEnglish() {
        return english;
    }
 
    public void setEnglish(int english) {
        this.english = english;
    }
 
    public int  getSum() {
        return  this.chinese + this.math + this.english;
    }
}
======================================
附上解析:
 int num = s 2.getSum() -  s1.getSum();
但是之前是這樣的
 int num = s 1.getSum() -  s2.getSum();
運行如下

 

成績並沒有從高到低,所以
 int num = s 2.getSum() -  s1.getSum();
再次運行

 

12.最后附上一個致命bug 關於eclipse:

eclispe 控制台光標位置bug
Eclipse控制台輸入數據后光標直接回到行首不跳到下一行

留意光標位置,要手動移動至下一行

 
不手動移到下一行會有莫明奇妙的異常
 
day17筆記補充
A:Collection集合總結(掌握)
    Collection
        |--List    有序,可重復
            |--ArrayList
                底層數據結構是數組,查詢快,增刪慢。
                線程不安全,效率高
            |--Vector
                底層數據結構是數組,查詢快,增刪慢。
                線程安全,效率低
            |--LinkedList
                底層數據結構是鏈表,查詢慢,增刪快。
                線程不安全,效率高
        |--Set    無序,唯一
            |--HashSet
                底層數據結構是哈希表。
                如何保證元素唯一性的呢?
                    依賴兩個方法:hashCode()和equals()
                    開發中自動生成這兩個方法即可
                |--LinkedHashSet
                    底層數據結構是鏈表和哈希表
                    由鏈表保證元素有序
                    由哈希表保證元素唯一
            |--TreeSet
                底層數據結構是紅黑樹。
                如何保證元素排序的呢?
                    自然排序
                    比較器排序
                如何保證元素唯一性的呢?
                    根據比較的返回值是否是0來決定
 
B:針對Collection集合我們到底使用誰呢?(掌握)
    唯一嗎?
        是:Set
            排序嗎?
                是:TreeSet
                否:HashSet
        如果你知道是Set,但是不知道是哪個Set,就用HashSet。
 
        否:List
            要安全嗎?
                是:Vector
                否:ArrayList或者LinkedList
                    查詢多:ArrayList
                    增刪多:LinkedList
        如果你知道是List,但是不知道是哪個List,就用ArrayList。
 
    如果你知道是Collection集合,但是不知道使用誰,就用ArrayList。
 
    如果你知道用集合,就用ArrayList。
 
C:在集合中常見的數據結構(掌握)
    ArrayXxx:底層數據結構是數組,查詢快,增刪慢
    LinkedXxx:底層數據結構是鏈表,查詢慢,增刪快
    HashXxx:底層數據結構是哈希表。依賴兩個方法:hashCode()和equals()
    TreeXxx:底層數據結構是二叉樹。兩種方式排序:自然排序和比較器排序

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM