国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

JavaSE進階 | Map集合、HashMap集合、TreeMap集合

這篇具有很好參考價值的文章主要介紹了JavaSE進階 | Map集合、HashMap集合、TreeMap集合。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

目錄

??Map集合概述?

??Map接口常用的方法

??哈希表(散列表)數(shù)據(jù)結構

??同時重寫HashCode和equals

??HashMap和Hashtable的區(qū)別

??Properties類

??TreeSet(TreeMap)集合

??自平衡二叉樹數(shù)據(jù)結構

??實現(xiàn)比較器接口

??集合工具類Collections


??Map集合概述?

(1)Map和Collection沒有繼承關系,是一個平級的關系。

(2)Map集合以key和value的方式存儲數(shù)據(jù):

鍵值對key和value都是引用數(shù)據(jù)類型。

key和value都是存儲對象的內存地址。

key起到主導的地位,value是key的一個附屬品。

④HashMap中的所有的key彼此之間是不可重復的、無序的。所有的key構成一個Set集合。key所在的類重寫hashCode()方法和equals()方法。

⑤HashMap中的value彼此之間是可重復的、無序的。所有的value就構成一個Collection集合。value所在的類要重寫equals()方法。

⑥HashMap中的一個key-value,就構成一個entry,所有的entry之間是不可重復的、無序的。所有的entry就構成一個Set集合。

(3)HashMap: 底層是哈希表,非線程安全的

(4)Hashtable: 底層也是哈希表,只不過線程是安全的,效率較低使用較少。

(5)Prorerties:線程是安全的,并且key和value只能儲存字符串String類型。

(6)TreeMap:底層是二叉樹,TreeMap集合的key可以自動按照大小順序排序。

(7)HashMap底層使用的是:數(shù)組+單向鏈表+紅黑樹結構進行存儲(JDK8之后)!

???Map集合繼承結構圖

JavaSE進階 | Map集合、HashMap集合、TreeMap集合

??Map接口常用的方法

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集合中元素個數(shù)是否為0
V remove(Object key)? 通過key刪除鍵值對
int size()? 獲取Map集合中鍵值對的個數(shù)
Set<K> keySet()? 獲取Map集合所有的key(所有的鍵(Key)是一個Set集合)

Collection<V> values()? 獲取Map集合中所有的value(所有的values是一個Collection集合)
Set<Map.Entry<K,V>> entrySet()? 將Map集合轉換成Set集合;對于Map結合轉換成Set集合怎么理解?假設現(xiàn)在有一個Map集合,如下所示: ? ? ??

Map集合對象? ??

??          key ????????????value
????????????----------------------------
????????????1 ??????????????zhangsan
????????????2 ??????????????lisi
????????????3 ??????????????wangwu
????????????4 ??????????????zhaoliu

通過Set set = map1.entrySet();set集合對象的形式,把Map集合的兩個值通過=的方式撮合成一個了??

1=zhangsan?
2=lisi??
3=wangwu
4=zhaoliu?

注意:Map集合通過entrySet()方法轉換成的這個Set集合,Set集合中元素的類型是 Map.Entry<K,V>;Map.Entry和String一樣,都是一種類型的名字,只不過:Map.Entry是靜態(tài)內部類,是Map中的靜態(tài)內部類 。

???回顧靜態(tài)內部類

package com.bjpowernode.javase.map;

public class Myclass {
    //聲明一個靜態(tài)內部類
    public static class InnerClass{

        // 靜態(tài)內部類的靜態(tài)方法
        public static void m1(){
            System.out.println("靜態(tài)內部類的靜態(tài)方法執(zhí)行!");
        }
        
        // 靜態(tài)內部類的實例方法
        public void m2(){
            System.out.println("靜態(tài)內部類的實例方法執(zhí)行!");
        }
    }

    public static void main(String[] args) {
        // 靜態(tài)方法執(zhí)行,類名:Myclass.InnerClass
        Myclass.InnerClass.m1();
        // 創(chuàng)建靜態(tài)內部類對象
        Myclass.InnerClass mi = new Myclass.InnerClass();
        mi.m2(); //執(zhí)行
        
        //給一個Set集合;改Set集合中存儲的對象是:MyClass.InnerClass類型
        Set<Myclass.InnerClass> set = new HashSet<>();

    }
}

??例1:

package com.bjpowernode.javase.map;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

public class MapTest02 {
    public static void main(String[] args) {
        // 創(chuàng)建Map集合對象
        Map<Integer,String> map = new HashMap<>();
        // 1、向Map集合中添加鍵值對;put方法
        map.put(1,"張三"); // 1是自動裝箱
        map.put(2,"李四");
        map.put(3,"王五");

        // 2、通過key獲取value;get方法
        String str = map.get(1);
        System.out.println(str); //張三

        // 3、獲取Map集合中鍵值對的個數(shù);size方法
        System.out.println(map.size()); //3

        // 4、 通過key刪除鍵值對;remove方法
        map.remove(1);
        System.out.println(map.size()); //2

        // contains方法底層調用的都是equals進行比對的,所以自定義的類型需要重寫equals方法。
        // 5、判斷Map中是否包含某個key;containsKey方法
        boolean b1 = map.containsKey(2);
        System.out.println(b1); // true

        // 6、判斷Map中是否包含某個value;containsValue方法
        boolean b2 = map.containsValue("李四");
        System.out.println(b2); // true

        // 7、獲取所有的value;values方法,返回的是一個Collection集合
        Collection<String> c = map.values();
        // 遍歷打印這個集合
        for(String s:c){ //增加for循環(huán)進行打印
            System.out.println(s);
        }

        // 8、清空集合;clear方法
        map.clear();
        System.out.println(map.size()); //0

        // 9、判斷Map集合是否為空;isEmpty方法
        System.out.println(map.isEmpty()); // true
    }
}

??例2:遍歷Map結合(重點)

對于Map集合的打印方式主要有兩種:

(1)第一種方式:先獲取所有的key,通過key獲取value

Map集合的所有key是一個Set集合,可以用keySet()方法進行獲得;

Map集合的所有value是一個Collection集合,可以用values()方法進行獲得;

所以我們就可以分為兩步:

第一步:先調用keySet()方法獲取所有的key,并返回一個Set集合;

第二步:再對Set集合迭代打印時,取出key;然后調用get(key)方法,通過key獲取到value

(2)第二種方式:調用entrySet()方法,將Map集合轉換成Set集合

①調用Set<Map.Entry<K,V>> entrySet()?轉換成Set集合;Map.Entry<K,V>是靜態(tài)內部類;

②轉換成Set集合后利用迭代器打印,在迭代器中獲取每一個節(jié)點Node(或者說entry,因為Node實現(xiàn)了Map.Entry接口)Map.Entry<Integer,String> node = it2.next();

③然后利用這個節(jié)點獲取key(node.getkey()方法) 和 value(value(node.getvalue()方法))

package com.bjpowernode.javase.map;

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

// Map集合遍歷
public class MapTest03 {
    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");
        // 先獲取所有的key,所有的key是一個Set集合
        Set<Integer> keys = map.keySet();
        // 在遍歷key,通過key獲取value
        //  方法1:利用迭代器
        Iterator<Integer> it = keys.iterator();
        while (it.hasNext()){
            Integer key = it.next(); //獲取其中一個key
            String value = map.get(key); //通過key獲取value
            System.out.println(key+"="+value);
        }

        //  方法2:foreach
        for(Integer key:keys){
            System.out.println(key+"="+map.get(key));
        }


        //第二種方式:? ?Set<Map.Entry<K,V>> entrySet()? 將Map集合轉換成Set集合
        Set<Map.Entry<Integer,String>> set = map.entrySet();
        // 方法1:使用迭代器進行打印
        Iterator<Map.Entry<Integer,String>>  it2 = set.iterator();
        while(it2.hasNext()){
            Map.Entry<Integer,String> node = it2.next(); //取出一個節(jié)點
            Integer key = node.getKey(); //取出節(jié)點的key
            String value = node.getValue(); //取出節(jié)點的value
            System.out.println(key+"="+value);
        }

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

    }
}

??補充:LinkedHashMap是HashMap的子類,在HashMap使用的數(shù)據(jù)結構的基礎上,增加了一對雙向鏈表,用于記錄添加的元素的先后順序,進而我們在遍歷元素時,就可以按照天機的順序顯示!開發(fā)中,對于頻繁的遍歷操作,建議使用此類!

??哈希表(散列表)數(shù)據(jù)結構

哈希表的存儲形式:哈希表實際上是一個數(shù)組和單向鏈表的結合體;底層實際上就是一個數(shù)組,這個數(shù)組中每一個元素是一個單向鏈表
數(shù)組:在查詢方面效率很高,隨機增刪方面效率很低。
單向鏈表:在隨機增刪方面效率較高,在查詢方面效率很低。
哈希表將以上的兩種數(shù)據(jù)結構融合在一起,充分發(fā)揮它們各自的優(yōu)點。

JavaSE進階 | Map集合、HashMap集合、TreeMap集合

(1)HashMap集合底層是哈希表/散列表的數(shù)據(jù)結構。
(2)對于存儲數(shù)據(jù)map.put(k,v)的原理:

第一步:先將k和v封裝到一個Node對象當中;

第二步:底層會調用k的hashCode()方法得到對應的hash值;然后通過哈希算法,將hash值轉換成數(shù)組的下標,下標位置如果沒有任何元素,就把Node添加到這個位置上;如果說下標對應的位置有鏈表存在,就把k和鏈表上的每一個節(jié)點中的k調用equals方法進行對比;如果所有的equals方法返回false,那么這個新節(jié)點就將添加到鏈表的末尾;如果其中一個equals方法返回true,那么這個節(jié)點的value將會被覆蓋!

(3)對于存儲數(shù)據(jù)map.get(k)的原理

第一步:先調用k的hashCode()方法得到對應的hash值;然后通過哈希算法,將hash值轉換成數(shù)組的下標,通過下標可以快速定位到某個位置

第二步:如果這個位置什么也沒有,返回null;如果這個位置上有鏈表,那么就會拿著k和鏈表上的每一個節(jié)點中的k調用equals方法進行對比;如果所有的equals方法都返回false,那么就反回null;如果其中有一個節(jié)點的equals返回true,那么此時這個節(jié)點的value就是我們get方法所需要的返回值

(4)HashMap集合底層的源代碼:

? ? public class HashMap{
? ? ? ? ? ? // HashMap底層實際上就是一個數(shù)組。(一維數(shù)組)
? ? ? ? ? ? Node<K,V>[] table;
? ? ? ? ? ? // 靜態(tài)的內部類HashMap.Node
? ? ? ? ? ? static class Node<K,V> {
? ? ? ? ? ? ? ? final int hash; // 哈希值(哈希值是key的hashCode()方法的執(zhí)行結果。
                               // hash值通過哈希函數(shù)/算法,可以轉換存儲成數(shù)組的下標。)
? ? ? ? ? ? ? ? final K key; // 存儲到Map集合中的那個key
? ? ? ? ? ? ? ? V value; // 存儲到Map集合中的那個value
? ? ? ? ? ? ? ? Node<K,V> next; // 下一個節(jié)點的內存地址。
? ? ? ? ? ? }
? ? ? ? }

(5)結論
重點:通過上面的講解可以得出HashMap集合的key,會先后調用兩個方法,?一個方法是hashCode(),一個方法是equals(),這兩個方法都需要重寫!
注意:同一個單向鏈表上所有節(jié)點的hash值相同,因為他們的數(shù)組下標是一樣的;但同一個鏈表上k和k的equals方法肯定返回的是false,都不相同(無序不可重復)
(6)HashMap集合的key部分特點無序,不可重復(重復會覆蓋)。
為什么無序? 因為不一定掛到哪個單向鏈表上。
不可重復是怎么保證的? equals方法來保證HashMap集合的key不可重復。
如果key重復了,value會覆蓋。
放在HashMap集合key部分的元素其實就是放到HashSet集合中了;所以HashSet集合中的元素也需要同時重寫hashCode()+equals()方法。

(7)哈希表HashMap使用不當時無法發(fā)揮性能?。ㄎ覀兛紤]兩個極端情況)
第一種情況:假設將所有的hashCode()方法返回值固定為某個值,那么會導致底層哈希表變成了純單向鏈表。這種情況我們成為:散列分布不均勻。
什么是散列分布均勻?
假設有100個元素,10個單向鏈表,那么每個單向鏈表上有10個節(jié)點,這是最好的,是散列分布均勻的。
第二種情況:假設將所有的hashCode()方法返回值都設定為不一樣的值,可以嗎?

不行,因為這樣的話導致底層哈希表就成為一維數(shù)組了,沒有鏈表的概念了,也是散列分布不均勻。所以要想散列分布均勻,需要重寫hashCode()方法時有一定的技巧。

注意:hashCode()方法返回值都一樣;實際上是一個單鏈表;

???????????hashCode()方法返回值都不一樣;實際上就是一個數(shù)組
(8)重點放在HashMap集合key部分的元素,實際上就是放在HashSet集合中的元素,需要同時重寫hashCode和equals方法。
(9)HashMap集合的默認初始化容量是16,默認加載因子是0.75;擴容:擴容后的容量是原容量的2倍;這個默認加載因子是當HashMap集合底層數(shù)組的容量達到75%的時候,數(shù)組開始擴容。
記?。?/strong>HashMap集合初始化容量必須是2的倍數(shù),這也是官方推薦的,這是因為達到散列均勻,為了提高HashMap集合的存取效率,所必須的。

package com.bjpowernode.javase.map;

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(111,"zhangsan");
        map.put(222,"lisi");
        map.put(333,"wangwu");
        map.put(333,"zhaoliu"); //key重復,value會覆蓋上面的值
        // 元素個數(shù)
        System.out.println(map.size()); //3
        // 遍歷
        Set<Map.Entry<Integer,String>> set = map.entrySet();
        for(Map.Entry<Integer,String> entry:set){
            System.out.println(entry.getKey()+"="+entry.getValue());
        }
        /*333=zhaoliu 
        222=lisi
        111=zhangsan
        驗證結果:無序不可重復,key重復會覆蓋掉原來的值!
        */
    }
}

??同時重寫HashCode和equals

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

(2)重要結論:如果一個類的equals方法重寫了,那么hashCode()方法必須重寫;并且equals方法返回如果是true,hashCode()方法返回的值必須一樣。
equals方法返回true表示兩個對象相同,在同一個單向鏈表上比較;那么對于同一個單向鏈表上的節(jié)點來說,他們的哈希值都是相同的,所以hashCode()方法的返回值也應該相同。

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

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

(5)對于哈希表數(shù)據(jù)結構來說:
如果o1和o2的hash值相同,一定是放到同一個單向鏈表上。
如果o1和o2的hash值不同,但由于哈希算法執(zhí)行結束之后轉換的數(shù)組下標可能相同,此時會發(fā)生“哈希碰撞”。

(6)JDK8對HashMap集合的改進:

如果哈希表單向鏈表中元素超過8個,單向鏈表這種數(shù)據(jù)結構會變成紅黑樹;當紅黑樹節(jié)點數(shù)量小于6時,會重新把紅黑樹變成單向鏈表;這種方式也是為了提高檢索效率,二叉樹的檢索效率會再次縮小掃描范圍,提高效率。

?學生類

package com.bjpowernode.javase.map;

import java.util.Objects;

public class Student {
    private String name;
    // 構造方法
    public Student() {
    }
    public Student(String name) {
        this.name = name;
    }

    // setter and getter
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    // 同時生成equals方法和hashCode方法
    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);
    }
    public int hashCode() {
        return Objects.hash(name);
    }
}

?測試?

package com.bjpowernode.javase.map;

import java.util.HashSet;
import java.util.Set;

public class HashMapTest02 {
    public static void main(String[] args) {
        Student s1 = new Student("張三");
        Student s2 = new Student("張三");

        // 重寫equlas方法之前
        System.out.println(s1.equals(s2)); // false
        // 重寫equals方法之后
        System.out.println(s1.equals(s2)); // true
        // 1163157884(重寫hashCode之后:774920)
        System.out.println("s1的hashCode是:"+s1.hashCode());
        // 1956725890(重寫hashCode之后:774920) 
        System.out.println("s2的hashCode是:"+s2.hashCode()); 
        System.out.println(s1.hashCode() == s2.hashCode()); // false

        // s1.equals(s2)結果已經是true了,表示s1和s2是一樣的,相同的,
        // 那么往HashSet集合中放的話,按說只能放進去1個。
        // (HashSet集合特點:無序不可重復)
        Set<Student> students = new HashSet<>();
        students.add(s1);
        students.add(s2);
        // 按理說應該是1,無序不可重復!未重寫hashCode方法
        System.out.println(students.size());  // 2
        // 重寫hashCode以后結果就是1
        System.out.println(students.size()); // 1

    }
}

??HashMap的key可以為null(HashTable的key不能為null)

HashMap集合key部分允許null嗎?
答:允許但是要注意HashMap集合的key null值只能有一個;多了會被后面的覆蓋

package com.bjpowernode.javase.map;

import java.util.HashMap;
import java.util.Map;

public class HashMapTest03 {
    public static void main(String[] args) {
        Map map = new HashMap();
        // HashMap集合允許key為null
        map.put(null,null);
        System.out.println(map.size()); // 1

        // key重復的話value會被覆蓋
        map.put(null,100);
        System.out.println(map.size()); // 還是1

        // 通過key獲取value
        System.out.println(map.get(null)); // 100
    }
}

??HashMap和Hashtable的區(qū)別

(1)Hashtable的key可以為null嗎?

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

(2)Hashtable方法都帶有synchronized:線程安全的。線程安全有其它的方案,Hashtable對線程的處理導致效率較低,使用較少了。Hashtable和HashMap一樣,底層都是哈希表數(shù)據(jù)結構。

(3)容量

①HashMap集合的默認初始化容量是16,默認加載因子是0.75;擴容后的容量是原容量的2倍
②Hashtable集合的默認初始化容量是11,默認加載因子是:0.75,擴容后:原容量 * 2 + 1

(4)底層數(shù)據(jù)結構

①HashMap底層使用的是:數(shù)組+單向鏈表+紅黑樹結構進行存儲(JDK8之后)!

②Hashtable底層使用的是:數(shù)組+單向鏈表!

package com.bjpowernode.javase.table;

import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;


public class HashtableTest01 {
    public static void main(String[] args) {
        //1、 HashMap集合的key和value都是可以為null的
        Map map1 = new HashMap();
        map1.put(null,null); // 編譯和運行都沒問題

        //2、 Hashtable的key和value都是不能為null的。
        Map map2 = new Hashtable();
        map2.put(null,"zhangsan"); // java.lang.NullPointerException
        map2.put(10,null); // java.lang.NullPointerException
    }
}

關于容量,擴容小總結:

Collection集合:

(1)ArrayList集合初始化容量是10;擴容到原容量的1.5倍!
(2)Vector集合初始化容量是10;擴容到原容量的2倍!
(3)HashSet集合初始化容量16,初始化容量建議是2的倍數(shù);擴容:擴容之后是原容量2倍

Map集合:

(1)HashMap初始化容量16,默認加載因子0.75,擴容之后的容量是量的2倍。
(2)Hashtable集合初始化容量11,默認加載因子0.75,擴容之后的容量是原容量*2 + 1

??Properties類

(1)Properties是一個Map集合,繼承Hashtable,Properties的key和value都是String類型。
(2)Properties被稱為屬性類對象,因為Hashtable是線程安全的,所以Properties是線程安全的。

(3)兩個重要方法

調用setProperties(key,value)方法存取數(shù)據(jù)。

調用getProperties(key)方法:通過key獲取value。

package com.bjpowernode.javase;

import java.util.Properties;

public class PropertiesTest01 {
    public static void main(String[] args) {
        // 創(chuàng)建一個Properties對象
        Properties pro = new Properties();
        //  存setProperyies
        pro.setProperty("username","root");
        pro.setProperty("password","1234");
        pro.setProperty("driver","com.mysql.jdbc.Driver");
        // 通過key取value
        System.out.println(pro.getProperty("username")); //root
        System.out.println(pro.getProperty("password")); //1234
        System.out.println(pro.getProperty("driver")); //com.mysql.jdbc.Driver
    }
}

注:Properties常用來處理屬性文件!

package com.zl.TreeSetTest;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

public class PropertiesTest {
    public static void main(String[] args) throws IOException {
        File file = new File("info.properties");
        // 查看這個屬性配置文件默認的位置(在工程的根目錄下)
        System.out.println(file.getAbsoluteFile()); // C:\Users\86177\IdeaProjects\spring-data-redis\info.properties
        // 需要一個輸入流
        FileInputStream fis = new FileInputStream(file);
        // 創(chuàng)建Properties集合
        Properties pro = new Properties();
        // 加載
        pro.load(fis);
        // 讀取數(shù)據(jù)(根據(jù)key)
        System.out.println(pro.getProperty("name")); // zhangsan
        System.out.println(pro.getProperty("password")); // 123

    }
}

??TreeSet(TreeMap)集合

(1)TreeSet集合底層實際上是一個TreeMap;放到TreeSet集合中的元素,等同于放到TreeMap集合key部分了。
(2)TreeMap集合底層是一個紅黑樹(自平衡的排序二叉樹)。
(3)TreeSet集合中的元素:無序不可重復,但是可以按照元素的大小順序自動排序(可排序集合),所以也叫作可排序集合(自然排序和定制排序)

(4)TreeSet集合有什么用呢?我們拿一個很常見的需求來作為例子;數(shù)據(jù)庫中有很多數(shù)據(jù):

? ? userid ?name ? ?     birth
? ? -------------------------------------
? ? 1 ? ? ? zs ? ? ? ? ?1980-11-11
? ? 2 ? ? ? ls ? ? ? ? ?1980-10-11
? ? 3 ? ? ? ww ? ? ? ? ?1981-11-11
? ? 4 ? ? ? zl ? ? ? ? ?1979-11-11

編寫程序從數(shù)據(jù)庫當中取出數(shù)據(jù),在頁面展示用戶信息的時候按照生日升序或者降序。
這個時候可以使用TreeSet集合,因為TreeSet集合放進去,拿出來就是有順序的。

package com.bjpowernode.javase.map;

import java.util.TreeSet;

public class TreeSetTest01 {
    public static void main(String[] args) {
        // 演示TreeSet對String是可排序的
        TreeSet<String> ts = new TreeSet<>();
        // 添加元素
        ts.add("zhangsan");
        ts.add("lisi");
        ts.add("wangwu");
        ts.add("wangliu");
        // 遍歷---升序排
        for(String s :ts){
            System.out.println(s); //  lisi、wangliu、wangwu、zhangsan
        }

        TreeSet<Integer> ts2 = new TreeSet<>();
        ts2.add(300);
        ts2.add(600);
        ts2.add(100);
        ts2.add(10);
        ts2.add(200);
        for(Integer i :ts2){
            System.out.println(i); // 10、100、200、300、600
        }
    }
}

??TreeSet無法對自定義類型排序

(1)對自定義的類型來說(例如Person類),TreeSet不可以排序。
以下程序中對于Person類型來說,無法排序;因為沒有指定Person對象之間的比較規(guī)則,誰大誰小并沒有說明。

(2)以下程序運行的時候出現(xiàn)了這個異常:?java.lang.ClassCastException
(3)出現(xiàn)這個異常的原因是:Person類沒有實現(xiàn)java.lang.Comparable接口。

(4)所以對于自定義的類型,使用TreeSet集合,因為沒有比較規(guī)則,所以是無法排序的;所以我們需要實現(xiàn)java.lang.Comparable接口;并且重寫compareTo方法,在compareTo方法里面進行比較規(guī)則的編寫,才可以!

?沒有實現(xiàn)Comparable接口,無法進行比較?

package com.bjpowernode.javase.map;

import java.util.TreeSet;

public class TreeSetTest02 {
    public static void main(String[] args) {
        // 創(chuàng)建對象
        Person p1 = new Person(32);
        Person p2 = new Person(20);
        Person p3 = new Person(30);
        // 創(chuàng)建集合
        TreeSet<Person> ts = new TreeSet<>();
        // 添加元素
        ts.add(p1);
        ts.add(p2);
        ts.add(p3);
        // 遍歷打印
        for(Person p:ts){
            System.out.println(p);
        }

    }
}

//自定義Person類
class Person{
    int age;
    public Person(int age){
        this.age = age;
    }

    // 重寫toString()方法
    public String toString(){
        return "Person[age="+age+"]";
    }

}

?實現(xiàn)Comparable接口,重寫compareTo方法,編寫比較的邏輯

package com.bjpowernode.javase.map;

import java.util.TreeSet;

public class TreeSetTest03 {
    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);

        // 創(chuàng)建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集合中的元素需要實現(xiàn)java.lang.Comparable接口。
// 并且實現(xiàn)compareTo方法。equals可以不寫。
class Customer implements Comparable<Customer>{

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

    // 需要在這個方法中編寫比較的邏輯,或者說比較的規(guī)則,按照什么進行比較!
    // k.compareTo(t.key)
    // 拿著參數(shù)k和集合中的每一個k進行比較,返回值可能是>0 <0 =0
    // 比較規(guī)則最終還是由程序員指定的:例如按照年齡升序。或者按照年齡降序。
    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; //升序
        return c.age - this.age; //降序
    }

    public String toString(){
        return "Customer[age="+age+"]";
    }
}

?比較規(guī)則怎么寫

我們不妨編寫一個:先按照年齡升序,如果年齡一樣的再按照姓名升序。
compareTo方法的返回值很重要:
①返回0表示相同,value會覆蓋。
②返回>0,會繼續(xù)在右子樹上找。
③返回<0,會繼續(xù)在左子樹上找。

我們也可以定義兩個比較規(guī)則,當一種比較規(guī)則失效時,在使用另外一種規(guī)則;

這里需要注意的是對于字符串的比較equals只能說明相等不相等;compareTof方法才能比較到底誰大誰小。

package com.bjpowernode.javase.map;

import java.util.TreeSet;

//先按照年齡升序,如果年齡一樣的再按照姓名升序。
public class TreeSetTest04 {
    public static void main(String[] args) {
        Vip v1 = new Vip("zhangsan",18);
        Vip v2 = new Vip("zhangzl",18);
        Vip v3 = new Vip("lisi",32);
        Vip v4 = new Vip("wangwu",20);
        Vip v5 = new Vip("zhaoliu",22);

        // 創(chuàng)建集合
        TreeSet<Vip> ts = new TreeSet<>();
        // 增加元素
        ts.add(v1);
        ts.add(v2);
        ts.add(v3);
        ts.add(v4);
        ts.add(v5);
        // 遍歷打印
        for(Vip v :ts){
            System.out.println(v);
        }


    }
}


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

    // 構造方法
    public Vip(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // 重寫toString方法
    public String toString() {
        return "Vip{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}'; //Vip{name='zhangsan', age=18}
    }

    // 重寫Comparable接口中中的方法
    public int compareTo(Vip o) {
        if(this.age != o.age){
            return this.age - o.age;
        }else{
            // 年齡相同,按照名字排序
            // 名字是String類型,可以直接比,調用compareTo來比較
            return this.name.compareTo(o.name);
        }

    }
}
/*
運行結果:
    Vip{name='zhangsan', age=18}
    Vip{name='zhangzl', age=18}
    Vip{name='wangwu', age=20}
    Vip{name='zhaoliu', age=22}
    Vip{name='lisi', age=32}
*/

??自平衡二叉樹數(shù)據(jù)結構

(1)TreeSet/TreeMap是自平衡二叉樹遵循左小右大原則存放。

(2)遍歷二叉樹的時候有三種方式:
①前序遍歷∶根左右
②中序遍歷∶左根右

③后序遍歷∶左右根
注意:前中后說的是“根”的位置,根在前面是前序、根在中間是中序、根在后面是后序

(3)TreeSet/TreeMap集合采用的是中序遍歷方式即Iterator迭代器采用的是中序遍歷方式

(4)我們就拿一組數(shù)據(jù),寫出它的二叉樹結構,來體驗一下中序遍歷的方式,例如:100 200 50 60 80 120 140 130 135 180 666 40 55

JavaSE進階 | Map集合、HashMap集合、TreeMap集合

(5)中序遍歷方式取出:40 50 55 60 80 100 120 130 135 140 180 200 666,按照中序遍歷的方式取出來的剛好是有序的。

??實現(xiàn)比較器接口

TreeSet集合中元素可排序的第二種方式:使用比較器的方式

(1)這種實現(xiàn)方式是根據(jù)源碼碼來定義的
如果我們使用無參的:調用的是Comparable接口里的compareTo方法;注意是自己定義的類型實現(xiàn)Comparable接口;這種方式不需要在構造方法new這個對象。

如果我們使用有參的:調用的是Comparator接口里的compare方法;注意是再另寫一個比較類去實現(xiàn)Comparator接口;這種方式需要在構造方法中去new實現(xiàn)的比較類。
Comparable是java.lang包下的,Comparator是java.util包下的
(2)結論:放到TreeSet或者TreeMap集合key部分的元素要想做到排序,包括兩種方式:
第一種:放在集合中的元素實現(xiàn)java.lang.Comparable接口。
第二種:在構造TreeSet或者TreeMap集合的時候給它傳一個比較器Comparator對象。
(3)Comparable和Comparator怎么選擇呢?
①當比較規(guī)則不會發(fā)生改變的時候,或者說當比較規(guī)則只有1個的時候,建議實現(xiàn)Comparable接口,重寫compareTo方法
②如果比較規(guī)則有多個,并且需要多個比較規(guī)則之間頻繁切換,建議使用Comparator接口;重寫compare方法,Comparator接口的設計符合OCP原則,。

package com.bjpowernode.javase.map;

import java.util.Comparator;
import java.util.TreeSet;

public class TreeSetTest05 {
    public static void main(String[] args) {
        Animals animals = new Animals(15);
        // 創(chuàng)建TreeSet集合的時候,需要使用這個比較器
        // TreeSet<Animals> animal = new TreeSet<>(); //原來這種方式就不行,沒有使用比較器
        // TreeSet<Animals> animal = new TreeSet<>(new AnimalComparator()); //new一個比較器對象傳過去

        // 這里也可以不寫Comparator接口的實現(xiàn),使用匿名內部類
        TreeSet<Animals> animal = new TreeSet<>(new Comparator<Animals>() {
            public int compare(Animals o1, Animals o2) {
                return o1.age - o2.age;
            }
        });

        animal.add(new Animals(100));
        animal.add(new Animals(80));
        animal.add(new Animals(81));

        // 循遍歷
        for(Animals a:animal){
            System.out.println(a);
        }
    }
}

class Animals{
    int age;
    // 構造方法
    public Animals(int age) {
        this.age = age;
    }
    // 重寫toString方法
    public String toString() {
        return "Animals{" +
                "age=" + age +
                '}'; // Animals{age=15}
    }
}

/*
// 單獨在這里編寫一個比較器
// 比較器實現(xiàn)java.util.Comparator接口。
class AnimalComparator implements Comparator<Animals> {

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

??集合工具類Collections

參考操作數(shù)組的工具類:Arrays,Collections 是一個操作 Set、List 和 Map 等集合的工具類。

(1)區(qū)分兩個類:

java.util.Collection 集合接口
java.util.Collections 集合工具類,方便集合的操作。

(2)通過Collections集合里的方法變成線程安全的;Collections.synchronizedList(集合)

(3)對于SortedSet集合是可排序集合,但是對于HashSet集合排序,可以先把HashSet集合通過new ArrayList<>(set);轉換成List集合,然后就可以使用Collections.sort(); 進行排序,因為使用這個sort方法排序只能是List集合才可以!

(4)對于自定義的類型如何排序呢?

可以把比較器作為參數(shù)傳進去,例如:Collections.sort(list集合,new Comparator比較器)

package com.bjpowernode.javase;

import java.util.*;

public class CollectionsTest {
    public static void main(String[] args) {
        // 1、 ArrayList集合不線程安全的
        List<String> list = new ArrayList<>();
        // 通過Collections集合里的方法變成線程安全的
        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); // abc abe abf abx
        }

        // 2、如果排序自己寫的類,需要自己實現(xiàn)compareTo接口
        List<WuGui2> wuGui2s = new ArrayList<>();
        wuGui2s.add(new WuGui2(1000));
        wuGui2s.add(new WuGui2(800));
        // 注意:對List集合中元素排序,需要保證List集合中的元素實現(xiàn)了:Comparable接口。
        Collections.sort(wuGui2s);
        for(WuGui2 w : wuGui2s){
            System.out.println(w);
        }

        // 3、對Set集合怎么排序呢?
        Set<String> set = new HashSet<>();
        set.add("king");
        set.add("kingsoft");
        set.add("king2");
        set.add("king1");
        //Collections.sort(); //里面只能是List集合
        // 所以需要把Set集合轉換成List集合
        List<String> mylist = new ArrayList<>(set);// 把set集合轉過來
        Collections.sort(mylist); //這樣就能排序了
        for(String s:mylist){
            System.out.println(s); // king king1 king2 kingsoft
        }

        // 自定義類型也可以排序,多傳一個我們上面講過的比較器參數(shù)。
        //Collections.sort(list集合, 比較器對象);

    }
}

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

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

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

?常用方法

Collections 中提供了一系列靜態(tài)的方法對集合元素進行排序、查詢和修改等操作,還提供了對集合對象設置不可變、對集合對象實現(xiàn)同步控制等方法(均為static方法)!

排序操作

- reverse(List):反轉 List 中元素的順序
- shuffle(List):對 List 集合元素進行隨機排序
- sort(List):根據(jù)元素的自然順序對指定 List 集合元素按升序排序
- sort(List,Comparator):根據(jù)指定的 Comparator 產生的順序對 List 集合元素進行排序
- swap(List,int, int):將指定 list 集合中的 i 處元素和 j 處元素進行交換
package com.zl.TreeSetTest;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class CollectionsTest {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1, 3, 7, 5, 4, 2, 15, 12);

        // reverse翻轉
        Collections.reverse(list);
        System.out.println(list); // [12, 15, 2, 4, 5, 7, 3, 1]

        // 隨機排序(相當于洗牌,每次都是隨機排序)
        Collections.shuffle(list);
        System.out.println(list); // [1, 15, 12, 5, 3, 2, 7, 4]

        // 進行排序(自然排序)
        Collections.sort(list);
        System.out.println(list); // [1, 2, 3, 4, 5, 7, 12, 15]

        // 指定排序(逆序)
        Collections.sort(list,(o1,o2)->{
            if (o1 instanceof Integer && o2 instanceof Integer){
                return -(o1.intValue() - o2.intValue()); // 逆序排加一個負號-
            }
            throw new RuntimeException("類型不匹配");
        });
        System.out.println(list); // [15, 12, 7, 5, 4, 3, 2, 1]

        // 交換(指定下標位置進行交換)
        Collections.swap(list,0,list.size()-1);
        System.out.println(list); // [1, 12, 7, 5, 4, 3, 2, 15]
    }
}

查找

- Object max(Collection):根據(jù)元素的自然順序,返回給定集合中的最大元素(最右邊的數(shù))
- Object max(Collection,Comparator):根據(jù) Comparator 指定的順序,返回給定集合中的最大元素(還是最右邊的數(shù),如果此時是按照降序排列的,實際上最右邊取的就是最小的數(shù)了)
- Object min(Collection):根據(jù)元素的自然順序,返回給定集合中的最小元素(最左邊的數(shù))
- Object min(Collection,Comparator):根據(jù) Comparator 指定的順序,返回給定集合中的最小元素
- int binarySearch(List list,T key)在List集合中查找某個元素的下標,但是List的元素必須是T或T的子類對象,而且必須是可比較大小的,即支持自然排序的。而且集合也事先必須是有序的,否則結果不確定。
- int binarySearch(List list,T key,Comparator c)在List集合中查找某個元素的下標,但是List的元素必須是T或T的子類對象,而且集合也事先必須是按照c比較器規(guī)則進行排序過的,否則結果不確定。
- int frequency(Collection c,Object o):返回指定集合中指定元素的出現(xiàn)次數(shù)
package com.zl.TreeSetTest;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class CollectionsTest {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1, 3, 7, 5, 4, 2, 15, 12);
        // 獲取最大值
        Integer max = Collections.max(list);
        System.out.println(max); // 15
        // 獲取最小值
        Integer min = Collections.min(list);
        System.out.println(min); // 1
        // 二分查找(必須提前有序)
        Collections.sort(list); // 排序
        System.out.println(list); // [1, 2, 3, 4, 5, 7, 12, 15]
        int flag = Collections.binarySearch(list, 5);// 二分查找
        System.out.println(flag); // 4
        // 某個元素在集合中出現(xiàn)的次數(shù)
        int frequency = Collections.frequency(list, 1);
        System.out.println(frequency); // 1

    }
}

復制、替換

- void copy(List dest,List src):將src中的內容復制到dest中
- boolean replaceAll(List list,Object oldVal,Object newVal):使用新值替換 List 對象的所有舊值
- 提供了多個unmodifiableXxx()方法,該方法返回指定 Xxx的不可修改的視圖。
package com.zl.TreeSetTest;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class CollectionsTest {
    public static void main(String[] args) {
        List<Integer> src = Arrays.asList(1, 3, 7, 5, 4, 2, 15, 12);
        // 直接拷貝會出現(xiàn)問題
        // 此時拷貝會出現(xiàn)異常,通過底層源碼發(fā)現(xiàn),會srcSize > dest.size()進行比較
        // 而dest.size()目前沒有元素肯定就是0,所以會拋出 Source does not fit in dest異常
        /*ArrayList<Integer> dest = new ArrayList<>();
        Collections.copy(dest,src);*/
        // 正確的做法
        List dest = Arrays.asList(new Object[src.size()]); // 相當于里面放了很多null
        Collections.copy(dest,src); // 拷貝的時候會覆蓋原來的值
        System.out.println(dest); // [1, 3, 7, 5, 4, 2, 15, 12]

        // 替換(也相當于修改)
        Collections.replaceAll(src,3,6);
        System.out.println(src); // [1, 6, 7, 5, 4, 2, 15, 12]

        // 把src變成只讀
        List<Integer> unmodifiableList = Collections.unmodifiableList(src);
        unmodifiableList.set(1,666); // UnsupportedOperationException不支持的操作異常,不能在修改

    }
}

添加

boolean addAll(Collection  c,T... elements)將所有指定元素添加到指定 collection 中。
package com.zl.TreeSetTest;

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

public class CollectionsTest {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        Collections.addAll(list,666,888,999); // 是一個可變長度的參數(shù)
        System.out.println(list); // [666, 888, 999]
    }
}

同步

Collections 類中提供了多個 synchronizedXxx() 方法,該方法可使將指定集合包裝成線程同步的集合,從而可以解決多線程并發(fā)訪問集合時的線程安全問題:

JavaSE進階 | Map集合、HashMap集合、TreeMap集合

?文章來源地址http://www.zghlxwxcb.cn/news/detail-405561.html

例題實戰(zhàn):模擬斗地主洗牌和發(fā)牌,牌沒有排序

package com.zl.TreeSetTest;

import java.util.ArrayList;
import java.util.Collections;

/**
 * Author:朗朗乾坤
 * Package:com.zl.TreeSetTest
 * Project:spring-data-redis
 *
 * @Date:2023/4/15 16:51
 */
public class CollectionsTest {
    public static void main(String[] args) {
        // 準備兩個字符數(shù)組
        String[] num = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"};
        String[] color = {"方片", "梅花", "紅桃", "黑桃"};
        ArrayList<String> poker = new ArrayList<>();
        // 嵌套遍歷,生成24張排放入poker集合當中
        for (int i = 0; i < color.length; i++) {
            for (int j = 0; j < num.length; j++) {
                poker.add(color[i] + num[j]);
            }
        }
        // 添加大小王
        poker.add("大王");
        poker.add("小王");
        // 洗牌
        Collections.shuffle(poker);
        //發(fā)牌
        ArrayList tomCards = new ArrayList();
        ArrayList jerryCards = new ArrayList();
        ArrayList meCards = new ArrayList();
        ArrayList lastCards = new ArrayList();
        for (int i = 0; i < poker.size(); i++) {
            if (i >= poker.size() - 3) {
                lastCards.add(poker.get(i));
            } else if (i % 3 == 0) {
                tomCards.add(poker.get(i));
            } else if (i % 3 == 1) {
                jerryCards.add(poker.get(i));
            } else {
                meCards.add(poker.get(i));
            }
        }
        //看牌
        System.out.println("Tom:\n" + tomCards);
        System.out.println("Jerry:\n" + jerryCards);
        System.out.println("me:\n" + meCards);
        System.out.println("底牌:\n" + lastCards);

    }
}

執(zhí)行結果:

JavaSE進階 | Map集合、HashMap集合、TreeMap集合

?

到了這里,關于JavaSE進階 | Map集合、HashMap集合、TreeMap集合的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯(lián)網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • Java----Hashmap,LinkedMap和TreeMap三者的區(qū)別

    Java----Hashmap,LinkedMap和TreeMap三者的區(qū)別

    ????????其中map表示的意思為“映射”,HashMap,LinkedMap和TreeMap這三中類都是對Map接口的實現(xiàn)類,在數(shù)據(jù)插入方面,HashMap是無序插入,LinkedMap是有序插入,而TreeMap會根據(jù)鍵的值進行排序后再進行插入。在運行方面,前兩個的運行速度較快,針對Map對象的存儲會選擇前兩者,

    2024年02月13日
    瀏覽(23)
  • 進階JAVA篇- Map 系列集合的遍歷方法與常用API

    進階JAVA篇- Map 系列集合的遍歷方法與常用API

    目錄 ? ? ? ? 1.0 Map 集合的說明 ? ? ? ? 1.1 Map 集合的常用方法 ? ? ? ? 1.2?Map 系列集合的特點 ? ? ? ? 2.0?Map 系列集合的遍歷方法(三種方法) ???????? 2.1 使用 keySet() 方法遍歷 ????????2.2 使用 entrySet() 方法遍歷 ????????2.3 使用 forEach() 方法遍歷(Java 8+) ?

    2024年02月08日
    瀏覽(29)
  • 從零開始學習 Java:簡單易懂的入門指南之HashMap及TreeMap源碼解讀(二十四)

    Tip: 1.TreeMap添加元素的時候,鍵是否需要重寫hashCode和equals方法? 此時是不需要重寫的。 2.HashMap是哈希表結構的,JDK8開始由數(shù)組,鏈表,紅黑樹組成的。既然有紅黑樹,HashMap的鍵是否需要實現(xiàn)Compareable接口或者傳遞比較器對象呢? 不需要的。 因為在HashMap的底層,默認是利用

    2024年02月07日
    瀏覽(17)
  • 如何遍歷HashMap集合?

    在Java中,HashMap是一種常用的數(shù)據(jù)結構,它提供了快速的查找、插入和刪除操作。當我們需要遍歷HashMap中的所有元素時,可以利用三種不同的方法實現(xiàn)。 HashMap中存儲的是鍵值對的形式,因此最簡單的方法就是直接遍歷鍵值對。我們可以通過以下代碼實現(xiàn): 上述代碼中,我們

    2023年04月23日
    瀏覽(19)
  • Java集合之一——HashMap(辨析)

    看到一篇講hashmap的文章,講的很不錯,但是有一點我覺得作者沒有講清楚,這里我說一下自己的理解。 原文,先看原文: https://blog.csdn.net/woshimaxiao1/article/details/83661464 前文概述,該博客的主要內容如下: 1. 什么是哈希表(主干為數(shù)組)、什么是哈希沖突、如何解決哈希沖突

    2024年02月15日
    瀏覽(18)
  • HashMap集合萬字源碼詳解(面試常考)

    HashMap集合萬字源碼詳解(面試???

    散列,又稱哈希(Hash),是一種數(shù)據(jù)處理方式。它通過特定的算法,將輸入(比如字符串、文件等)轉換成固定長度的一串(通常是數(shù)字),并且這個過程是不可逆的。這個過程中的算法就稱為哈希函數(shù),得到的結果就稱為哈希值。 散列的主要作用是為了檢索數(shù)據(jù)。通過散

    2024年02月02日
    瀏覽(18)
  • JavaSE(集合框架)

    Java 集合框架 Java Collection Framework ,又被稱為容器 container ,是定義在 java.util 包下的一組接口 interfaces 和其實現(xiàn)類 classes 。其主要表現(xiàn)為將多個元素 element 置于一個單元中,用于對這些元素進行快速、便捷的存儲、檢索 、管理 。 Collection:是一個接口,包含了大部分容器常用

    2024年04月25日
    瀏覽(18)
  • 【Java-14】3萬字深入理解HashMap集合(高級)

    【Java-14】3萬字深入理解HashMap集合(高級)

    ? HashMap基于哈希表的Map接口實現(xiàn),是以key-value存儲形式存在,即主要用來存放鍵值對。HashMap 的實現(xiàn)不是同步的,這意味著它不是線程安全的。它的key、value都可以為null。此外,HashMap中的映射不是有序的。 ? JDK1.8 之前 HashMap 由 數(shù)組+鏈表 組成的,數(shù)組是 HashMap 的主體,鏈

    2024年02月11日
    瀏覽(26)
  • Java 大廠面試 —— 常見集合篇 List HashMap 紅黑樹

    Java 大廠面試 —— 常見集合篇 List HashMap 紅黑樹

    23Java面試專題 八股文面試全套真題(含大廠高頻面試真題)多線程_軟工菜雞的博客-CSDN博客 02-算法復雜度分析 2.1 數(shù)組 2.1.1 數(shù)組概述 數(shù)組(Array)是一種用 連續(xù)的內存空間 存儲 相同數(shù)據(jù)類型 數(shù)據(jù)的線性數(shù)據(jù)結構。 我們定義了這么一個數(shù)組之后,在內存的表示是這樣的:

    2024年02月11日
    瀏覽(19)
  • 【數(shù)據(jù)類型】Collections.synchronizedMap 多線程Map,與HashMap的不同

    Collections.synchronizedMap 是 Java 中提供的工具方法,用于創(chuàng)建一個同步(線程安全)的 Map。 它接受一個現(xiàn)有的 Map 對象,并返回一個通過同步包裝后的 Map 。 下面是一個簡單的示例: 1、基礎原理 Collections.synchronizedMap 是通過返回一個線程安全的 Map 包裝器來實現(xiàn)的,它在對 Map

    2024年01月18日
    瀏覽(17)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包