Javase進階--集合--動力節點(該文章是我在B站上所看視頻寫的筆記)

集合

什麼是集合?有什麼用?

	數組其實就是一個集合。集合實際上就是一個容器。可以來容納其它類型的數據。

集合爲什麼說在開發中使用較多?

集合是一個容器,是一個載體,可以一次容納多個對象。
在實際開發中,假設連接數據庫,數據庫當中有10條記錄,
那麼假設把這10條記錄查詢出來,在java程序中會將10條數據封裝成10個java對象,
然後將10個java對象放到某一個集合當中,將集合傳到前端,
然後遍歷集合,將一個數據一個數據展現出來。

集合不能直接存儲基本數據類型,另外集合也不能直接存儲java對象,

集合當中存儲的都是java對象的內存地址。(或者說集合中存儲的是引用。)
	list.add(100); //自動裝箱Integer
	注意:
		集合在java中本身是一個容器,是一個對象。
		集合中任何時候存儲的都是“引用”。

在java中每一個不同的集合,底層會對應不同的數據結構。

往不同的集合中存儲元素,等於將數據放到了不同的數據結構當中。
什麼是數據結構?數據存儲的結構就是數據結構。
不同的數據結構,數據存儲方式不同。

例如:

	數組、二叉樹、鏈表、哈希表...
	以上這些都是常見的數據結構。
		你往集合c1中放數據,可能是放到數組上了。
		你往集合c2中放數據,可能是放到二叉樹上了。
		.....
	你使用不同的集合等同於使用了不同的數據結構。
		new ArrayList(); 創建一個集合,底層是數組。
		new LinkedList(); 創建一個集合對象,底層是鏈表。
		new TreeSet(); 創建一個集合對象,底層是二叉樹。
	.....

所有的集合類和集合接口都在java.util包下。

	java.util.*;

在java中集合分爲兩大類:

一類是單個方式存儲元素:

單個方式存儲元素,這一類集合中超級父接口:java.util.Collection;

Collection中能存放什麼元素?

沒有使用“泛型”之前,Collection中可以存儲Object的所有子類型。
使用了“泛型”之後,Collection中只能存儲某個具體的類型。
集合後期我們會學習“泛型”語法。目前先不用管。Collection中什麼都能存,
只要是Object的子類型就行。(集合中不能直接存儲基本數據類型,也不能存java對象,只是存儲java對象的內存地址。)

Collection中的常用方法

 boolean add(Object e) 向集合中添加元素
 int size()  獲取集合中元素的個數
 void clear() 清空集合
 boolean contains(Object o) 判斷當前集合中是否包含元素o,包含返回true,不包含返回false
 boolean remove(Object o) 刪除集合中的某個元素。
 boolean isEmpty()  判斷該集合中元素的個數是否爲0
 Object[] toArray()  調用這個方法可以把集合轉換成數組。【作爲了解,使用不多。】
代碼演示:(Collection常用方法)
import java.util.ArrayList;
import java.util.Collection;

public class CollectionTest01 {
    public static void main(String[] args) {
        // 創建一個集合對象
        //Collection c = new Collection(); // 接口是抽象的,無法實例化。
        // 多態
        Collection c = new ArrayList();
        // 測試Collection接口中的常用方法
        c.add(1200); // 自動裝箱(java5的新特性。),實際上是放進去了一個對象的內存地址。Integer x = new Integer(1200);
        c.add(3.14); // 自動裝箱
        c.add(new Object());
        c.add(new Student());
        c.add(true); // 自動裝箱

        // 獲取集合中元素的個數
        System.out.println("集合中元素個數是:" + c.size()); // 5

        // 清空集合
        c.clear();
        System.out.println("集合中元素個數是:" + c.size()); // 0

        // 再向集合中添加元素
        c.add("hello"); // "hello"對象的內存地址放到了集合當中。
        c.add("world");
        c.add("浩克");
        c.add("綠巨人");
        c.add(1);

        // 判斷集合中是否包含"綠巨人"
        boolean flag = c.contains("綠巨人");
        System.out.println(flag); // true
        boolean flag2 = c.contains("綠巨人2");
        System.out.println(flag2); // false
        System.out.println(c.contains(1)); // true

        System.out.println("集合中元素個數是:" + c.size()); // 5

        // 刪除集合中某個元素
        c.remove(1);
        System.out.println("集合中元素個數是:" + c.size()); // 4

        // 判斷集合是否爲空(集合中是否存在元素)
        System.out.println(c.isEmpty()); // false
        // 清空
        c.clear();
        System.out.println(c.isEmpty()); // true(true表示集合中沒有元素了!)

        c.add("abc");
        c.add("def");
        c.add(100);
        c.add("helloworld!");
        c.add(new Student());

        // 轉換成數組(瞭解,使用不多。)
        Object[] objs = c.toArray();
        for(int i = 0; i < objs.length; i++){
            // 遍歷數組
            Object o = objs[i];
            System.out.println(o);
        }
    }
}

class Student{

}

集合遍歷/迭代(重點*****)

 步驟:第一步:獲取集合對象的迭代器對象Iterator
	  第二步:通過以上獲取的迭代器對象開始迭代/遍歷集合。
       以下兩個方法是迭代器對象Iterator中的方法:
           boolean hasNext()如果仍有元素可以迭代,則返回 true。
           Object next() 返回迭代的下一個元素。
 注意:以下講解的遍歷方式/迭代方式,是所有Collection通用的一種方式。
 		在Map集合中不能用。在所有的Collection以及子類中使用。
代碼演示:(HashSet和ArrayList集合)
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.HashSet;
public class CollectionTest02 {
    public static void main(String[] args) {
        // 創建集合對象
		 // ArrayList集合:有序可重複
        Collection c = new ArrayList();
        // 添加元素
        c.add("abc");
        c.add("def");
        c.add(100);
        c.add(new Object());
		c.add(100);
        // 對集合Collection進行遍歷/迭代
        // 第一步:獲取集合對象的迭代器對象Iterator
        Iterator it = c.iterator();
        // 第二步:通過以上獲取的迭代器對象開始迭代/遍歷集合。
        while(it.hasNext()){
            // 存進去是什麼類型,取出來還是什麼類型。
            Object obj = it.next();
            /*if(obj instanceof Integer){
                System.out.println("Integer類型");
            }*/
            // 只不過在輸出的時候會轉換成字符串。因爲這裏println會調用toString()方法。
            System.out.println(obj);
        }

        // HashSet集合:無序不可重複
        Collection c2 = new HashSet();
        // 無序:存進去和取出的順序不一定相同。
        // 不可重複:存儲100,不能再存儲100.
        c2.add(100);
        c2.add(200);
        c2.add(300);
        c2.add(90);
        c2.add(400);
        c2.add(50);
        c2.add(60);
        c2.add(100);
        Iterator it2 = c2.iterator();
        while(it2.hasNext()){
            System.out.println(it2.next());
        }
    }
}

深入Collection集合的contains方法和equals方法:

boolean contains(Object o)
    判斷集合中是否包含某個對象o
    如果包含返回true, 如果不包含返回false。

contains方法是用來判斷集合中是否包含某個元素的方法,
那麼它在底層是怎麼判斷集合中是否包含某個元素的呢?
    調用了equals方法進行比對。
    equals方法返回true,就表示包含這個元素。

結論:存放在一個集合中的類型,一定要重寫equals方法。

代碼演示:
import java.util.ArrayList;
import java.util.Collection;

/*
測試contains方法
測試remove方法。

 */
public class CollectionTest05 {
    public static void main(String[] args) {
        // 創建集合對象
        Collection c = new ArrayList();
        // 創建用戶對象
        User u1 = new User("jack");
        // 加入集合
        c.add(u1);

        // 判斷集合中是否包含u2
        User u2 = new User("jack");

        // 沒有重寫equals之前:這個結果是false
        //System.out.println(c.contains(u2)); // false
        // 重寫equals方法之後,比較的時候會比較name。
        System.out.println(c.contains(u2)); // true

        c.remove(u2);
        System.out.println(c.size()); // 0

        /*Integer x = new Integer(10000);
        c.add(x);

        Integer y = new Integer(10000);
        System.out.println(c.contains(y)); // true*/

        // 創建集合對象
        Collection cc = new ArrayList();
        // 創建字符串對象
        String s1 = new String("hello");
        // 加進去。
        cc.add(s1);

        // 創建了一個新的字符串對象
        String s2 = new String("hello");
        // 刪除s2
        cc.remove(s2); // s1.equals(s2) java認爲s1和s2是一樣的。刪除s2就是刪除s1。
        // 集合中元素個數是?
        System.out.println(cc.size()); // 0
    }
}

class User{
    private String name;
    public User(){}
    public User(String name){
        this.name = name;
    }

    // 重寫equals方法
    // 將來調用equals方法的時候,一定是調用這個重寫的equals方法。
    // 這個equals方法的比較原理是:只要姓名一樣就表示同一個用戶。
    public boolean equals(Object o) {
        if(o == null || !(o instanceof User)) return false;
        if(o == this) return true;
        User u = (User)o;
        // 如果名字一樣表示同一個人。(不再比較對象的內存地址了。比較內容。)
        return u.name.equals(this.name);
    }

}

集合元素中的remove

重點:當集合的結構發生改變時,迭代器必須重新獲取,
	如果還是用以前老的迭代器,會出現 異常:java.util.ConcurrentModificationException

重點:在迭代集合元素的過程中,不能調用集合對象的remove方法,刪除元素:  c.remove(o); 迭代過程中不能這樣。  
	會出現:java.util.ConcurrentModificationException

重點:在迭代元素的過程當中,一定要使用迭代器Iterator的remove方法,刪除元素, 不要使用集合自帶的remove方法刪除元素。
代碼演示
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class CollectionTest06 {
    public static void main(String[] args) {
        // 創建集合
        Collection c = new ArrayList();

        // 注意:此時獲取的迭代器,指向的是那是集合中沒有元素狀態下的迭代器。
        // 一定要注意:集合結構只要發生改變,迭代器必須重新獲取。
        // 當集合結構發生了改變,迭代器沒有重新獲取時,調用next()方法時:java.util.ConcurrentModificationException
        Iterator it = c.iterator();

        // 添加元素
        c.add(1); // Integer類型
        c.add(2);
        c.add(3);

        // 獲取迭代器
        //Iterator it = c.iterator();
        /*while(it.hasNext()){
            // 編寫代碼時next()方法返回值類型必須是Object。
            // Integer i = it.next();
            Object obj = it.next();
            System.out.println(obj);
        }*/

        Collection c2 = new ArrayList();
        c2.add("abc");
        c2.add("def");
        c2.add("xyz");

        Iterator it2 = c2.iterator();
        while(it2.hasNext()){
            Object o = it2.next();
            // 刪除元素
            // 刪除元素之後,集合的結構發生了變化,應該重新去獲取迭代器
            // 但是,循環下一次的時候並沒有重新獲取迭代器,所以會出現異常:java.util.ConcurrentModificationException
            // 出異常根本原因是:集合中元素刪除了,但是沒有更新迭代器(迭代器不知道集合變化了)
            //c2.remove(o); // 直接通過集合去刪除元素,沒有通知迭代器。(導致迭代器的快照和原集合狀態不同。)
            // 使用迭代器來刪除可以嗎?
            // 迭代器去刪除時,會自動更新迭代器,並且更新集合(刪除集合中的元素)。
            it2.remove(); // 刪除的一定是迭代器指向的當前元素。
            System.out.println(o);
        }

        System.out.println(c2.size()); //0
    }
}

ArrayList集合

1、默認初始化容量10(底層先創建了一個長度爲0的數組,當添加第一個元素的時候,初始化容量10。)
2、集合底層是一個Object[]數組。
3、構造方法:
    new ArrayList();
    new ArrayList(20);
4、ArrayList集合的擴容:
    增長到原容量的1.5倍。
    ArrayList集合底層是數組,怎麼優化?
        儘可能少的擴容。因爲數組擴容效率比較低,建議在使用ArrayList集合
        的時候預估計元素的個數,給定一個初始化容量。
5、數組優點:
    檢索效率比較高。(每個元素佔用空間大小相同,內存地址是連續的,知道首元素內存地址,
    然後知道下標,通過數學表達式計算出元素的內存地址,所以檢索效率最高。)
6、數組缺點:
    隨機增刪元素效率比較低。
    另外數組無法存儲大數據量。(很難找到一塊非常巨大的連續的內存空間。)
7、向數組末尾添加元素,效率很高,不受影響。
8、面試官經常問的一個問題?
    這麼多的集合中,你用哪個集合最多?
        答:ArrayList集合。
        因爲往數組末尾添加元素,效率不受影響。
        另外,我們檢索/查找某個元素的操作比較多。
9、ArrayList集合是非線程安全的。(不是線程安全的集合。)
代碼演示

import java.util.ArrayList;
import java.util.List;

/*

 */
public class ArrayListTest01 {
    public static void main(String[] args) {

        // 默認初始化容量是10
        // 數組的長度是10
        List list1 = new ArrayList();
        // 集合的size()方法是獲取當前集合中元素的個數。不是獲取集合的容量。
        System.out.println(list1.size()); // 0

        // 指定初始化容量
        // 數組的長度是20
        List list2 = new ArrayList(20);
        // 集合的size()方法是獲取當前集合中元素的個數。不是獲取集合的容量。
        System.out.println(list2.size()); // 0

        list1.add(1);
        list1.add(2);
        list1.add(3);
        list1.add(4);
        list1.add(5);
        list1.add(6);
        list1.add(7);
        list1.add(8);
        list1.add(9);
        list1.add(10);

        System.out.println(list1.size());

        // 再加一個元素
        list1.add(11);
        System.out.println(list1.size()); // 11個元素。
        /*
        int newCapacity = ArraysSupport.newLength(oldCapacity,minCapacity - oldCapacity,oldCapacity >> 1);
         */
        // 100 二進制轉換成10進制: 00000100右移一位 00000010 (2)  【4 / 2】
        // 原先是4、現在增長:2,增長之後是6,增長之後的容量是之前容量的:1.5倍。
        // 6是4的1.5倍
    }
}

HashSet集合轉換爲List集合

代碼演示:
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;

/*
集合ArrayList的構造方法
 */
public class ArrayListTest02 {
    public static void main(String[] args) {

        // 默認初始化容量10
        List myList1 = new ArrayList();

        // 指定初始化容量100
        List myList2 = new ArrayList(100);

        // 創建一個HashSet集合
        Collection c = new HashSet();
        // 添加元素到Set集合
        c.add(100);
        c.add(200);
        c.add(900);
        c.add(50);

        // 通過這個構造方法就可以將HashSet集合轉換成List集合。
        List myList3 = new ArrayList(c);
        for(int i = 0; i < myList3.size(); i++){
            System.out.println(myList3.get(i));
        }
    }
}

Vactor集合

1、底層也是一個數組。
2、初始化容量:10
3、怎麼擴容的?
    擴容之後是原容量的2倍。
    10--> 20 --> 40 --> 80
4、ArrayList集合擴容特點:
    ArrayList集合擴容是原容量1.5倍。
5、Vector中所有的方法都是線程同步的,都帶有synchronized關鍵字,是線程安全的。效率比較低,使用較少了。
6、怎麼將一個線程不安全的ArrayList集合轉換成線程安全的呢?
    使用集合工具類:
        java.util.Collections;
        java.util.Collection 是集合接口。
        java.util.Collections 是集合工具類。
代碼演示
import java.util.*;
public class VectorTest {
    public static void main(String[] args) {
        // 創建一個Vector集合
        List vector = new Vector();
        //Vector vector = new Vector();

        // 添加元素
        // 默認容量10個。
        vector.add(1);
        vector.add(2);
        vector.add(3);
        vector.add(4);
        vector.add(5);
        vector.add(6);
        vector.add(7);
        vector.add(8);
        vector.add(9);
        vector.add(10);

        // 滿了之後擴容(擴容之後的容量是20.)
        vector.add(11);

        Iterator it = vector.iterator();
        while(it.hasNext()){
            Object obj = it.next();
            System.out.println(obj);
        }

        // 這個可能以後要使用!!!!
        List myList = new ArrayList(); // 非線程安全的。

        // 變成線程安全的
        Collections.synchronizedList(myList); // 這裏沒有辦法看效果,因爲多線程沒學,你記住先!

        // myList集合就是線程安全的了。
        myList.add("111");
        myList.add("222");
        myList.add("333");
    }
}

鏈表:LinkedList

鏈表的優點:
    由於鏈表上的元素在空間存儲上內存地址不連續。
    所以隨機增刪元素的時候不會有大量元素位移,因此隨機增刪效率較高。
    在以後的開發中,如果遇到隨機增刪集合中元素的業務比較多時,建議
    使用LinkedList。
    
     LinkedList集合底層也是有下標的。
     注意:ArrayList之所以檢索效率比較高,不是單純因爲下標的原因。是因爲底層數組發揮的作用。
    LinkedList集合照樣有下標,但是檢索/查找某個元素的時候效率比較低,因爲只能從頭節點開始一個一個遍歷。

鏈表的缺點:
    不能通過數學表達式計算被查找元素的內存地址,每一次查找都是從頭
    節點開始遍歷,直到找到爲止。所以LinkedList集合檢索/查找的效率
    較低。

 ArrayList:把檢索發揮到極致。(末尾添加元素效率還是很高的。)
 LinkedList:把隨機增刪發揮到極致。
 加元素都是往末尾添加,所以ArrayList用的比LinkedList多。
   
鏈表沒有初始化容量,最初鏈表是沒有任何元素的,first和last都是null。
代碼演示
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/*

 */
public class LinkedListTest01 {
    public static void main(String[] args) {
        
        List list = new LinkedList();
        list.add("a");
        list.add("b");
        list.add("c");

        for(int i = 0; i <list.size(); i++){
            Object obj = list.get(i);
            System.out.println(obj);
        }

        // LinkedList集合有初始化容量嗎?沒有。
        // 最初這個鏈表中沒有任何元素。first和last引用都是null。
        // 不管是LinkedList還是ArrayList,以後寫代碼時不需要關心具體是哪個集合。
        // 因爲我們要面向接口編程,調用的方法都是接口中的方法。
        //List list2 = new ArrayList(); // 這樣寫表示底層你用了數組。
        List list2 = new LinkedList(); // 這樣寫表示底層你用了雙向鏈表。

        // 以下這些方法你面向的都是接口編程。
        list2.add("123");
        list2.add("456");
        list2.add("789");

        for(int i = 0; i < list2.size(); i++){
            System.out.println(list2.get(i));
        }

    }
}

一類是以鍵值對兒的方式存儲元素

以鍵值對的方式存儲元素,這一類集合中超級父接口:java.util.Map;

Map

java.util.Map接口中常用的方法:
1、Map和Collection沒有繼承關係。
2、Map集合以key和value的方式存儲數據:鍵值對
    key和value都是引用數據類型。
    key和value都是存儲對象的內存地址。
    key起到主導的地位,value是key的一個附屬品。
3、Map接口中常用方法:
    V put(K key, V value) 向Map集合中添加鍵值對
    V get(Object key) 通過key獲取value
    void clear()    清空Map集合
    boolean containsKey(Object key) 判斷Map中是否包含某個key
    boolean containsValue(Object value) 判斷Map中是否包含某個value
    boolean isEmpty()   判斷Map集合中元素個數是否爲0
    V remove(Object key) 通過key刪除鍵值對
    int size() 獲取Map集合中鍵值對的個數。
    Collection<V> values() 獲取Map集合中所有的value,返回一個Collection

    Set<K> keySet() 獲取Map集合所有的key(所有的鍵是一個set集合)

    Set<Map.Entry<K,V>> entrySet()
        將Map集合轉換成Set集合
        假設現在有一個Map集合,如下所示:
            map1集合對象
            key             value
            ----------------------------
            1               zhangsan
            2               lisi
            3               wangwu
            4               zhaoliu

            Set set = map1.entrySet();
            set集合對象
            1=zhangsan 【注意:Map集合通過entrySet()方法轉換成的這個Set集合,Set集合中元素的類型是 Map.Entry<K,V>】
            2=lisi     【Map.Entry和String一樣,都是一種類型的名字,只不過:Map.Entry是靜態內部類,是Map中的靜態內部類】
            3=wangwu
            4=zhaoliu ---> 這個東西是個什麼?Map.Entry
代碼演示:
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

public class MapTest01 {
    public static void main(String[] args) {
        // 創建Map集合對象
        Map<Integer, String> map = new HashMap<>();
        // 向Map集合中添加鍵值對
        map.put(1, "zhangsan"); // 1在這裏進行了自動裝箱。
        map.put(2, "lisi");
        map.put(3, "wangwu");
        map.put(4, "zhaoliu");
        // 通過key獲取value
        String value = map.get(2);
        System.out.println(value);
        // 獲取鍵值對的數量
        System.out.println("鍵值對的數量:" + map.size());
        // 通過key刪除key-value
        map.remove(2);
        System.out.println("鍵值對的數量:" + map.size());
        // 判斷是否包含某個key
        // contains方法底層調用的都是equals進行比對的,所以自定義的類型需要重寫equals方法。
        System.out.println(map.containsKey(new Integer(4))); // true
        // 判斷是否包含某個value
        System.out.println(map.containsValue(new String("wangwu"))); // true

        // 獲取所有的value
        Collection<String> values = map.values();
        // foreach
        for(String s : values){
            System.out.println(s);
        }

        // 清空map集合
        map.clear();
        System.out.println("鍵值對的數量:" + map.size());
        // 判斷是否爲空
        System.out.println(map.isEmpty()); // true
    }
}

Map集合遍歷:

代碼演示:
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/*
Map集合的遍歷。【非常重要】
 */
public class MapTest02 {
    public static void main(String[] args) {

        // 第一種方式:獲取所有的key,通過遍歷key,來遍歷value
        Map<Integer, String> map = new HashMap<>();
        map.put(1, "zhangsan");
        map.put(2, "lisi");
        map.put(3, "wangwu");
        map.put(4, "zhaoliu");
        // 遍歷Map集合
        // 獲取所有的key,所有的key是一個Set集合
        Set<Integer> keys = map.keySet();
        // 遍歷key,通過key獲取value
        // 迭代器可以
        /*Iterator<Integer> it = keys.iterator();
        while(it.hasNext()){
            // 取出其中一個key
            Integer key = it.next();
            // 通過key獲取value
            String value = map.get(key);
            System.out.println(key + "=" + value);
        }*/
        // foreach也可以
        for(Integer key : keys){
            System.out.println(key + "=" + map.get(key));
        }

        // 第二種方式:Set<Map.Entry<K,V>> entrySet()
        // 以上這個方法是把Map集合直接全部轉換成Set集合。
        // Set集合中元素的類型是:Map.Entry
        Set<Map.Entry<Integer,String>> set = map.entrySet();
        // 遍歷Set集合,每一次取出一個Node
        // 迭代器
        /*Iterator<Map.Entry<Integer,String>> it2 = set.iterator();
        while(it2.hasNext()){
            Map.Entry<Integer,String> node = it2.next();
            Integer key = node.getKey();
            String value = node.getValue();
            System.out.println(key + "=" + value);
        }*/

        // foreach
        // 這種方式效率比較高,因爲獲取key和value都是直接從node對象中獲取的屬性值。
        // 這種方式比較適合於大數據量。
        for(Map.Entry<Integer,String> node : set){
            System.out.println(node.getKey() + "--->" + node.getValue());
        }
    }
}

HashMap集合

HashMap集合:
1、HashMap集合底層是哈希表/散列表的數據結構。
2、哈希表是一個怎樣的數據結構呢?
    哈希表是一個數組和單向鏈表的結合體。
    數組:在查詢方面效率很高,隨機增刪方面效率很低。
    單向鏈表:在隨機增刪方面效率較高,在查詢方面效率很低。
    哈希表將以上的兩種數據結構融合在一起,充分發揮它們各自的優點。
3、HashMap集合底層的源代碼:
    public class HashMap{
        // HashMap底層實際上就是一個數組。(一維數組)
        Node<K,V>[] table;
        // 靜態的內部類HashMap.Node
        static class Node<K,V> {
            final int hash; // 哈希值(哈希值是key的hashCode()方法的執行結果。hash值通過哈希函數/算法,可以轉換存儲成數組的下標。)
            final K key; // 存儲到Map集合中的那個key
            V value; // 存儲到Map集合中的那個value
            Node<K,V> next; // 下一個節點的內存地址。
        }
    }
    哈希表/散列表:一維數組,這個數組中每一個元素是一個單向鏈表。(數組和鏈表的結合體。)
4、最主要掌握的是:
    map.put(k,v)
    v = map.get(k)
    以上這兩個方法的實現原理,是必須掌握的。
5、HashMap集合的key部分特點:
    無序,不可重複。
    爲什麼無序? 因爲不一定掛到哪個單向鏈表上。
    不可重複是怎麼保證的? equals方法來保證HashMap集合的key不可重複。
    如果key重複了,value會覆蓋。

    放在HashMap集合key部分的元素其實就是放到HashSet集合中了。
    所以HashSet集合中的元素也需要同時重寫hashCode()+equals()方法。

6、哈希表HashMap使用不當時無法發揮性能!
    假設將所有的hashCode()方法返回值固定爲某個值,那麼會導致底層哈希表變成了
    純單向鏈表。這種情況我們成爲:散列分佈不均勻。
    什麼是散列分佈均勻?
        假設有100個元素,10個單向鏈表,那麼每個單向鏈表上有10個節點,這是最好的,
        是散列分佈均勻的。
    假設將所有的hashCode()方法返回值都設定爲不一樣的值,可以嗎,有什麼問題?
        不行,因爲這樣的話導致底層哈希表就成爲一維數組了,沒有鏈表的概念了。
        也是散列分佈不均勻。
    散列分佈均勻需要你重寫hashCode()方法時有一定的技巧。
7、重點:放在HashMap集合key部分的元素,以及放在HashSet集合中的元素,需要同時重寫hashCode和equals方法。
8、HashMap集合的默認初始化容量是16,默認加載因子是0.75
    這個默認加載因子是當HashMap集合底層數組的容量達到75%的時候,數組開始擴容。

    重點,記住:HashMap集合初始化容量必須是2的倍數,這也是官方推薦的,
    這是因爲達到散列均勻,爲了提高HashMap集合的存取效率,所必須的。
代碼演示:
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/*

 */
public class HashMapTest01 {
    public static void main(String[] args) {
        // 測試HashMap集合key部分的元素特點
        // Integer是key,它的hashCode和equals都重寫了。
        Map<Integer,String> map = new HashMap<>();
        map.put(1111, "zhangsan");
        map.put(6666, "lisi");
        map.put(7777, "wangwu");
        map.put(2222, "zhaoliu");
        map.put(2222, "king"); //key重複的時候value會自動覆蓋。

        System.out.println(map.size()); // 4

        // 遍歷Map集合
        Set<Map.Entry<Integer,String>> set = map.entrySet();
        for(Map.Entry<Integer,String> entry : set){
            // 驗證結果:HashMap集合key部分元素:無序不可重複。
            System.out.println(entry.getKey() + "=" + entry.getValue());
        }
    }
}

HashCode

1、向Map集合中存,以及從Map集合中取,都是先調用key的hashCode方法,然後再調用equals方法!
equals方法有可能調用,也有可能不調用。
    拿put(k,v)舉例,什麼時候equals不會調用?
        k.hashCode()方法返回哈希值,
        哈希值經過哈希算法轉換成數組下標。
        數組下標位置上如果是null,equals不需要執行。
    拿get(k)舉例,什麼時候equals不會調用?
        k.hashCode()方法返回哈希值,
        哈希值經過哈希算法轉換成數組下標。
        數組下標位置上如果是null,equals不需要執行。

2、注意:如果一個類的equals方法重寫了,那麼hashCode()方法必須重寫。
並且equals方法返回如果是true,hashCode()方法返回的值必須一樣。
    equals方法返回true表示兩個對象相同,在同一個單向鏈表上比較。
    那麼對於同一個單向鏈表上的節點來說,他們的哈希值都是相同的。
    所以hashCode()方法的返回值也應該相同。

3、hashCode()方法和equals()方法不用研究了,直接使用IDEA工具生成,但是這兩個方法需要同時生成。

4、終極結論:
    放在HashMap集合key部分的,以及放在HashSet集合中的元素,需要同時重寫hashCode方法和equals方法。

5、對於哈希表數據結構來說:
    如果o1和o2的hash值相同,一定是放到同一個單向鏈表上。
    當然如果o1和o2的hash值不同,但由於哈希算法執行結束之後轉換的數組下標可能相同,此時會發生“哈希碰撞”。
 HashMap集合key部分允許null嗎?
允許
但是要注意:HashMap集合的key null值只能有一個。
代碼演示(深入版):
import java.util.Objects;
import java.util.HashSet;
import java.util.Set;	

public class HashMapTest02 {
    public static void main(String[] args) {

        Student s1 = new Student("zhangsan");
        Student s2 = new Student("zhangsan");

        // 重寫equals方法之前是false
        //System.out.println(s1.equals(s2)); // false

        // 重寫equals方法之後是true
        System.out.println(s1.equals(s2)); //true (s1和s2表示相等)

        System.out.println("s1的hashCode=" + s1.hashCode()); //284720968 (重寫hashCode之後-1432604525)
        System.out.println("s2的hashCode=" + s2.hashCode()); //122883338 (重寫hashCode之後-1432604525)

        // s1.equals(s2)結果已經是true了,表示s1和s2是一樣的,相同的,那麼往HashSet集合中放的話,
        // 按說只能放進去1個。(HashSet集合特點:無序不可重複)
        Set<Student> students = new HashSet<>();
        students.add(s1);
        students.add(s2);
        System.out.println(students.size()); // 這個結果按說應該是1. 但是結果是2.顯然不符合HashSet集合存儲特點。怎麼辦?
    }
}
class Student {
    private String name;

    public Student() {
    }

    public Student(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    // hashCode

    // equals(如果學生名字一樣,表示同一個學生。)
    /*public boolean equals(Object obj){
        if(obj == null || !(obj instanceof Student)) return false;
        if(obj == this) return true;
        Student s = (Student)obj;
        return this.name.equals(s.name);
    }*/

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name);
    }
}

Hashtable

Hashtable的key可以爲null嗎?
    Hashtable的key和value都是不能爲null的。
    HashMap集合的key和value都是可以爲null的。

Hashtable方法都帶有synchronized:線程安全的。
線程安全有其它的方案,這個Hashtable對線程的處理
導致效率較低,使用較少了。

Hashtable和HashMap一樣,底層都是哈希表數據結構。
Hashtable的初始化容量是11,默認加載因子是:0.75f
Hashtable的擴容是:原容量 * 2 + 1
代碼演示
import java.util.Hashtable;
import java.util.Map;

public class HashtableTest01 {
    public static void main(String[] args) {
        Map map = new Hashtable();

        //map.put(null, "123");
        map.put(100, null);
    }
}

Properties

代碼演示:
Prope	rties是一個Map集合,繼承Hashtable,Properties的key和value都是String類型。
Properties被稱爲屬性類對象。
Properties是線程安全的。
import java.util.Properties;

public class PropertiesTest01 {
    public static void main(String[] args) {

        // 創建一個Properties對象
        Properties pro = new Properties();

        // 需要掌握Properties的兩個方法,一個存,一個取。
        pro.setProperty("url", "jdbc:mysql://localhost:3306/bjpowernode");
        pro.setProperty("driver","com.mysql.jdbc.Driver");
        pro.setProperty("username", "root");
        pro.setProperty("password", "123");

        // 通過key獲取value
        String url = pro.getProperty("url");
        String driver = pro.getProperty("driver");
        String username = pro.getProperty("username");
        String password = pro.getProperty("password");

        System.out.println(url);
        System.out.println(driver);
        System.out.println(username);
        System.out.println(password);

    }
}

TreeSet

1、TreeSet集合底層實際上是一個TreeMap
2、TreeMap集合底層是一個二叉樹。
3、放到TreeSet集合中的元素,等同於放到TreeMap集合key部分了。
4、TreeSet集合中的元素:無序不可重複,但是可以按照元素的大小順序自動排序。(根據字典順序排序)
稱爲:可排序集合。

對自定義的類型來說,TreeSet可以排序嗎?
    可以排序,但是放在TreeSet集合中的元素需要實現java.lang.Comparable接口。
				並且實現(重寫)compareTo方法。equals可以不寫。

如果不重寫方法會出現以下異常:
    java.lang.ClassCastException:
        class com.bjpowernode.javase.collection.Person
        cannot be cast to class java.lang.Comparable
出現這個異常的原因是:
    Person類沒有實現java.lang.Comparable接口。
代碼演示:(TreeSet排序)
import java.util.TreeSet;

public class TreeSetTest04 {
    public static void main(String[] args) {
        Customer c1 = new Customer(32);
        Customer c2 = new Customer(20);
        Customer c3 = new Customer(30);
        Customer c4 = new Customer(25);

        // 創建TreeSet集合
        TreeSet<Customer> customers = new TreeSet<>();
        // 添加元素
        customers.add(c1);
        customers.add(c2);
        customers.add(c3);
        customers.add(c4);

        // 遍歷
        for (Customer c : customers){
            System.out.println(c);
        }
    }
}

// 放在TreeSet集合中的元素需要實現java.lang.Comparable接口。
// 並且實現compareTo方法。equals可以不寫。
class Customer implements Comparable<Customer>{

    int age;
    public Customer(int age){
        this.age = age;
    }

    // 需要在這個方法中編寫比較的邏輯,或者說比較的規則,按照什麼進行比較!
    // k.compareTo(t.key)
    // 拿着參數k和集合中的每一個k進行比較,返回值可能是>0 <0 =0
    // 比較規則最終還是由程序員指定的:例如按照年齡升序。或者按照年齡降序。
    @Override
    public int compareTo(Customer c) { // c1.compareTo(c2);
        // this是c1
        // c是c2
        // c1和c2比較的時候,就是this和c比較。
        /*int age1 = this.age;
        int age2 = c.age;
        if(age1 == age2){
            return 0;
        } else if(age1 > age2) {
            return 1;
        } else {
            return -1;
        }*/
        //return this.age - c.age; // =0 >0 <0
        return c.age - this.age;
    }

    public String toString(){
        return "Customer[age="+age+"]";
    }
}
代碼演示(深入版):
import java.util.TreeSet;
/*
先按照年齡升序,如果年齡一樣的再按照姓名升序。
 */
public class TreeSetTest05 {
    public static void main(String[] args) {
        TreeSet<Vip> vips = new TreeSet<>();
        vips.add(new Vip("zhangsi", 20));
        vips.add(new Vip("zhangsan", 20));
        vips.add(new Vip("king", 18));
        vips.add(new Vip("soft", 17));
        for(Vip vip : vips){
            System.out.println(vip);
        }
    }
}

class Vip implements Comparable<Vip>{
    String name;
    int age;

    public Vip(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Vip{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    /*
    compareTo方法的返回值很重要:
        返回0表示相同,value會覆蓋。
        返回>0,會繼續在右子樹上找。【10 - 9 = 1 ,1 > 0的說明左邊這個數字比較大。所以在右子樹上找。】
        返回<0,會繼續在左子樹上找。
     */
    @Override
    public int compareTo(Vip v) {
        // 寫排序規則,按照什麼進行比較。
        if(this.age == v.age){
            // 年齡相同時按照名字排序。
            // 姓名是String類型,可以直接比。調用compareTo來完成比較。
            return this.name.compareTo(v.name);
        } else {
            // 年齡不一樣
            return this.age - v.age;
        }
    }
}

TreeSet的第二種排序方法:比較器

TreeSet集合中元素可排序的第二種方式:使用比較器的方式。
最終的結論:
    放到TreeSet或者TreeMap集合key部分的元素要想做到排序,包括兩種方式:
        第一種:放在集合中的元素實現java.lang.Comparable接口。
        第二種:在構造TreeSet或者TreeMap集合的時候給它傳一個比較器對象。
Comparable和Comparator怎麼選擇呢?
    當比較規則不會發生改變的時候,或者說當比較規則只有1個的時候,建議實現Comparable接口。
    如果比較規則有多個,並且需要多個比較規則之間頻繁切換,建議使用Comparator接口。

    Comparator接口的設計符合OCP原則。
代碼演示:
import java.util.Comparator;
import java.util.TreeSet;

public class TreeSetTest06 {
    public static void main(String[] args) {
        // 創建TreeSet集合的時候,需要使用這個比較器。
        // TreeSet<WuGui> wuGuis = new TreeSet<>();//這樣不行,沒有通過構造方法傳遞一個比較器進去。

        // 給構造方法傳遞一個比較器。
        //TreeSet<WuGui> wuGuis = new TreeSet<>(new WuGuiComparator());

        // 大家可以使用匿名內部類的方式(這個類沒有名字。直接new接口。)
        TreeSet<WuGui> wuGuis = new TreeSet<>(new Comparator<WuGui>() {
            @Override
            public int compare(WuGui o1, WuGui o2) {
                return o1.age - o2.age;
            }
        });

        wuGuis.add(new WuGui(1000));
        wuGuis.add(new WuGui(800));
        wuGuis.add(new WuGui(810));

        for(WuGui wuGui : wuGuis){
            System.out.println(wuGui);
        }
    }
}

// 烏龜
class WuGui{

    int age;

    public WuGui(int age){
        this.age = age;
    }

    @Override
    public String toString() {
        return "小烏龜[" +
                "age=" + age +
                ']';
    }
}

// 單獨在這裏編寫一個比較器
// 比較器實現java.util.Comparator接口。(Comparable是java.lang包下的。Comparator是java.util包下的。)
/*
class WuGuiComparator implements Comparator<WuGui> {

    @Override
    public int compare(WuGui o1, WuGui o2) {
        // 指定比較規則
        // 按照年齡排序
        return o1.age - o2.age;
    }
}
 */

Collections工具類

java.util.Collection 集合接口
java.util.Collections 集合工具類,方便集合的操作。
代碼演示:
import java.util.*;

public class CollectionsTest {
    public static void main(String[] args) {

        // ArrayList集合不是線程安全的。
        List<String> list = new ArrayList<>();

        // 變成線程安全的
        Collections.synchronizedList(list);

        // 排序
        list.add("abf");
        list.add("abx");
        list.add("abc");
        list.add("abe");

        Collections.sort(list);
        for(String s : list){
            System.out.println(s);
        }

        List<WuGui2> wuGuis = new ArrayList<>();
        wuGuis.add(new WuGui2(1000));
        wuGuis.add(new WuGui2(8000));
        wuGuis.add(new WuGui2(500));
        // 注意:對List集合中元素排序,需要保證List集合中的元素實現了:Comparable接口。
        Collections.sort(wuGuis);
        for(WuGui2 wg : wuGuis){
            System.out.println(wg);
        }

        // 對Set集合怎麼排序呢?
        Set<String> set = new HashSet<>();
        set.add("king");
        set.add("kingsoft");
        set.add("king2");
        set.add("king1");
        // 將Set集合轉換成List集合
        List<String> myList = new ArrayList<>(set);
        Collections.sort(myList);
        for(String s : myList) {
            System.out.println(s);
        }

        // 這種方式也可以排序。
        //Collections.sort(list集合, 比較器對象);
    }
}

class WuGui2 implements Comparable<WuGui2>{
    int age;
    public WuGui2(int age){
        this.age = age;
    }

    @Override
    public int compareTo(WuGui2 o) {
        return this.age - o.age;
    }

    @Override
    public String toString() {
        return "WuGui2{" +
                "age=" + age +
                '}';
    }
}

泛型(JDK5之後)

泛型這種語法機制,旨在程序編譯階段起作用,只是給編譯器參考的。(運行階段泛型沒用)
泛型的好處:
    集合中存儲的元素類型統一了。
    從集合中取出來的元素類型是泛型指定的類型,不需要進行大量的“向下轉型”
泛型的缺點:
    導致集合中存儲的怨怒缺乏多樣性。
大多數業務中,集合中元素的類型還是統一的,所以這種泛型特性被大家所認可。
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class GenericTest01 {
    public static void main(String[] args) {
        // JDK8之後引入了自動推斷機制(又稱鑽石表達式)
        //以下兩種寫法均可,JDK8以後最好用第二種
        //List<Animal> myList = new ArrayList<Animal>();
        List<Animal> myList = new ArrayList<>();
        Cat c = new Cat();
        Bird b = new Bird();
        myList.add(c);
        myList.add(b);
        //獲取迭代器,這個表示迭代器迭代的是Animal類型
        Iterator<Animal> it = myList.iterator();
        while (it.hasNext()){
            //使用泛型之後,每一次迭代返回的數據都是Animal類型
            Animal a = it.next();
            //調用父類方法不需要進行強制類型轉換了,直接調用
            a.move();
            //調用子類方法需要進行強制類型轉換。
            if(a instanceof Cat){
                Cat c2 = (Cat)a;
                c2.catMove();
            }
            if (a instanceof Bird){
                Bird b2 = (Bird)a;
                b2.birdmove();
            }
        };
    }
}
class Animal{
    public void move(){
        System.out.println("動物在走路");
    }
}
class Cat extends Animal{
    public void catMove(){
        System.out.println("貓在走貓步");
    }
}
class Bird extends Animal{
    public void birdmove(){
        System.out.println("鳥兒在飛翔");
    }
}

foreach使用

增強for(foreach)
語法:
	for(元素數據類型 變量名 : 數組或集合){
	}
代碼演示
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/*
集合使用foreach
 */
public class ForEachTest02 {
    public static void main(String[] args) {
        // 創建List集合
        List<String> strList = new ArrayList<>();

        // 添加元素
        strList.add("hello");
        strList.add("world!");
        strList.add("kitty!");

        // 遍歷,使用迭代器方式
        Iterator<String> it = strList.iterator();
        while(it.hasNext()){
            String s = it.next();
            System.out.println(s);
        }

        // 使用下標方式(只針對於有下標的集合)
        for(int i = 0; i < strList.size(); i++){
            System.out.println(strList.get(i));
        }

        // 使用foreach
        for(String s : strList){ // 因爲泛型使用的是String類型,所以是:String s
            System.out.println(s);
        }

        List<Integer> list = new ArrayList<>();
        list.add(100);
        list.add(200);
        list.add(300);
        for(Integer i : list){ // i代表集合中的元素
            System.out.println(i);
        }
    }
}

代碼大總結(所需掌握基礎描述)

主要掌握的內容:
1.每個計劃對象的創建(new)
2,向集合中添加元素
3,從集合中取出某個元素
4,遍歷集合

主要的集合類:
ArrayList
LinkedList
HashSet(HashMap中的key,存儲在HashMap集合key的元素需要同時重寫hashCode + equals)
TreeSet
HashMap
Properties
TreeMap

代碼演示:ArrayList

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;

public class ArrayListTest {
    public static void main(String[] args) {
        //創建ArrayList集合對象
        //ArrayList<String> list = new ArrayList<>();
        //創建LinkedList
        LinkedList<String> list = new LinkedList<>();
        //往集合裏面添加元素
        list.add("123123");
        list.add("123asd3");
        list.add("123ad3");
        list.add("11e123");
        //從集合中取出某個元素:list有下標,用下標取出
        String s = list.get(0);
        System.out.println(s);
        //遍歷:forr循環遍歷
        System.out.println("for循環遍歷-----");
        for (int i = 0; i <list.size() ; i++) {
            String s1 = list.get(i);
            System.out.println(s1);
        }
        //迭代器遍歷
        System.out.println("以下爲迭代器遍歷:——————");
        Iterator<String> it = list.iterator();
        while (it.hasNext()){
            String s2 = it.next();
            System.out.println(s2);
        }
        System.out.println("while循環改爲for循環遍歷----");
        for (Iterator<String> it2 = list.iterator(); it.hasNext();){
            System.out.println(it2.next());
        }
        //foreach遍歷
        System.out.println("以下爲foreach遍歷---------");
        for (String s3 : list){
            System.out.println(s3);
        }
    }
}

代碼演示:HashMap

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class HashMapTest {
    public static void main(String[] args) {
        //創建map集合:
        HashMap<Integer,String> map = new HashMap<>();
        map.put(1,"asda");
        map.put(56,"dsf");
        map.put(21,"sdf");
        map.put(13,"asda");
        map.put(1,"adasd");//key重複會覆蓋
        //獲取map集合的個數
        System.out.println(map.size());
        //獲取map集合key爲2的數據
        System.out.println(map.get(2));
        //Map集合遍歷
        Set<Integer> keys = map.keySet();
        for (Integer key : keys){
            System.out.println(key + " = " +map.get(key));
        }
        System.out.println("-----------");
        //第二種方法:將Map集合轉換爲Set集合,Set集合中每個元素是Node,Node節點中有key,value
        Set<Map.Entry<Integer,String>> nodes = map.entrySet();
        for (Map.Entry<Integer,String> node : nodes){
            System.out.println(node.getKey() + " = " +node.getValue());
        }

    }
}

代碼演示:HashSet

import java.util.HashSet;
import java.util.Iterator;
import java.util.Objects;

/*
HashSet的特點:無序不可重複。
HashSet是HashMap的key值。
自定義類中需要重寫toString,HashCode,equals方法
* */

public class HashSetTest {
    public static void main(String[] args) {
        //創建一個HashSet集合
        HashSet<Student> set = new HashSet<>();
        //添加元素:無序不可重複
        set.add(new Student(123,"a"));
        set.add(new Student(235,"a"));
        set.add(new Student(123,"a"));
        //迭代器遍歷集合
        Iterator<Student> iterator = set.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
        System.out.println("---------");
        //foreach遍歷集合
        for (Student s : set){
            System.out.println(s);
        }
    }
}

class Student{
    int num;
    String name;

    public Student(int num, String name) {
        this.num = num;
        this.name = name;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return num == student.num &&
                Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(num, name);
    }

    @Override
    public String toString() {
        return "Student{" +
                "num=" + num +
                ", name='" + name + '\'' +
                '}';
    }
}

代碼演示:TreeSet

import java.util.Comparator;
import java.util.Iterator;
import java.util.Objects;
import java.util.TreeSet;
/*
* TreeSet集合有序不可重複
* */
public class TreeSetTst {
    public static void main(String[] args) {
        TreeSet<A> treeSet = new TreeSet<>();
        treeSet.add(new A("1"));
        treeSet.add(new A("1"));
        treeSet.add(new A("7"));
        treeSet.add(new A("2"));
        //迭代器遍歷
        Iterator<A> it = treeSet.iterator();
        while (it.hasNext()){
            System.out.println(it.next());
        }
        System.out.println("------------");
        //foreach遍歷
        for (A s : treeSet){
            System.out.println(s);
        }
        System.out.println("----------");
        //new BComparator()比較器
        TreeSet<B> tree = new TreeSet<>(new BComparator());
        tree.add(new B(1,"asda"));
        tree.add(new B(5,"asda"));
        tree.add(new B(1,"ahdf"));
        tree.add(new B(2,"wer"));
        //迭代器遍歷
        Iterator<B> iterator2 = tree.iterator();
        while (iterator2.hasNext()){
            System.out.println(iterator2.next());
        }

        System.out.println("------------");
        //將它倒序:傳入比較器,匿名內部類
        TreeSet<String> treeSet1 = new TreeSet<>(new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return Integer.valueOf(o2) - Integer.valueOf(o1);//o1-o2爲升序,o2-o1爲降序
            }
        });
        treeSet1.add("11");
        treeSet1.add("12");
        treeSet1.add("19");
        treeSet1.add("11");
        treeSet1.add("16");
        Iterator<String> it2 = treeSet1.iterator();
        while (it2.hasNext()){
            System.out.println(it2.next());
        }

    }
}
//第一種自定義類,比較器
class A implements Comparable<A>{
    String name;

    public A(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "A{" +
                "name='" + name + '\'' +
                '}';
    }

    @Override
    public int compareTo(A o) {
        return Integer.valueOf(this.name)-Integer.valueOf(o.name);
    }
}
//第二種自定義類的比較器Comparator
class B{
    int i;
    String name;

    public B(int i, String name) {
        this.i = i;
        this.name = name;
    }

    @Override
    public String toString() {
        return "B{" +
                "i=" + i +
                ", name='" + name + '\'' +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        B b = (B) o;
        return i == b.i &&
                Objects.equals(name, b.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(i, name);
    }
}
//Comparator比較器:
class BComparator implements Comparator<B>{

    @Override
    public int compare(B o1, B o2) {
        return o1.i-o2.i;
    }
}

代碼演示:ProperTies

import java.util.Iterator;
import java.util.Properties;
import java.util.Set;

public class ProperTiesTest {
    public static void main(String[] args) {
        Properties pro = new Properties();
        //存數據:
        pro.setProperty("wqe","ad");
        pro.setProperty("qwe","zfa");
        pro.setProperty("qwe","fhgg");
        //取數據:
        String username = pro.getProperty("qwe");
        String password = pro.getProperty("wqe");
        System.out.println(username);
        System.out.println(password);

    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章