Java集合框架Set&Map詳細(xì)解析
第一章 Map集合
Map 是 Java 集合框架中用于存儲(chǔ)鍵值對(duì)(Key-Value) 的接口,它允許通過(guò)鍵(Key)快速查找對(duì)應(yīng)的值(Value),屬于非線性集合。與 Collection 接口(存儲(chǔ)單元素)不同,Map 存儲(chǔ)的是 “鍵值對(duì)映射關(guān)系”,鍵具有唯一性(不允許重復(fù)),而值可以重復(fù)。
1.1 常見的Map集合
HashMap<K,V>:存儲(chǔ)數(shù)據(jù)采用的哈希表結(jié)構(gòu),元素的存取順序不能保證一致。由于要保證鍵的唯一、不重復(fù),需要重寫鍵的hashCode()方法、equals()方法。
LinkedHashMap<K,V>:HashMap下有個(gè)子類LinkedHashMap,存儲(chǔ)數(shù)據(jù)采用的哈希表結(jié)構(gòu)+鏈表結(jié)構(gòu)。通過(guò)鏈表結(jié)構(gòu)可以保證元素的存取順序一致;通過(guò)哈希表結(jié)構(gòu)可以保證的鍵的唯一、不重復(fù),需要重寫鍵的hashCode()方法、equals()方法。
TreeMap<K,V>:TreeMap集合和Map相比沒有特有的功能,底層的數(shù)據(jù)結(jié)構(gòu)是紅黑樹;可以對(duì)元素的鍵進(jìn)行排序,排序方式有兩種:自然排序和比較器排序。
1.2 Map的常用方法
Map接口中定義了很多方法,常用的如下:
public V put(K key, V value): 把指定的鍵與指定的值添加到Map集合中。public V remove(Object key): 把指定的鍵 所對(duì)應(yīng)的鍵值對(duì)元素 在Map集合中刪除,返回被刪除元素的值。public V get(Object key)根據(jù)指定的鍵,在Map集合中獲取對(duì)應(yīng)的值。public Set<K> keySet(): 獲取Map集合中所有的鍵,存儲(chǔ)到Set集合中。public Set<Map.Entry<K,V>> entrySet(): 獲取到Map集合中所有的鍵值對(duì)對(duì)象的集合(Set集合)。public boolean containKey(Object key):判斷該集合中是否有此鍵。
1.3 Map的遍歷方法
一、遍歷所有鍵(keySet())
通過(guò) keySet() 方法獲取所有鍵的 Set 集合,再通過(guò)鍵獲取對(duì)應(yīng)的值。
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MapTraversal {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
map.put("蘋果", 5);
map.put("香蕉", 3);
map.put("橙子", 7);
// 1. 遍歷所有鍵,再通過(guò)鍵獲取值
Set<String> keys = map.keySet(); // 獲取鍵的集合
for (String key : keys) {
Integer value = map.get(key); // 通過(guò)鍵獲取值
System.out.println(key + " → " + value);
}
}
}二、遍歷所有鍵值對(duì)(entrySet())
通過(guò) entrySet() 方法獲取所有鍵值對(duì)的 Set 集合,直接從鍵值對(duì)對(duì)象中獲取鍵和值。
// 2. 遍歷所有鍵值對(duì)(推薦,效率最高)
Set<Map.Entry<String, Integer>> entries = map.entrySet(); // 獲取鍵值對(duì)集合
for (Map.Entry<String, Integer> entry : entries) {
String key = entry.getKey(); // 獲取鍵
Integer value = entry.getValue(); // 獲取值
System.out.println(key + " → " + value);
}三、遍歷所有值(values())
// 3. 僅遍歷值(無(wú)法獲取對(duì)應(yīng)鍵)
for (Integer value : map.values()) {
System.out.println("值:" + value);
}四、迭代器(Iterator)遍歷
通過(guò)迭代器遍歷 keySet() 或 entrySet(),支持在遍歷中安全刪除元素。
import java.util.Iterator;
// 4. 迭代器遍歷 entrySet(支持遍歷中刪除)
Iterator<Map.Entry<String, Integer>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, Integer> entry = iterator.next();
System.out.println(entry.getKey() + " → " + entry.getValue());
// 遍歷中刪除元素(必須用迭代器的 remove() 方法,否則拋異常)
if (entry.getValue() < 5) {
iterator.remove();
}
}1.4 HashMap的使用
HashMap 是 Java 集合框架中基于哈希表實(shí)現(xiàn)的 Map 接口實(shí)現(xiàn)類,用于存儲(chǔ)鍵值對(duì)(Key-Value),其特點(diǎn)為:
1.可以存放鍵值對(duì)
2.鍵不允許重復(fù)存放,依據(jù)是添加進(jìn)來(lái)的元素的鍵 hashCode()和 equals()
3.存取順序不一致
4.允許存放null鍵、null值(鍵最多只能有一個(gè) null)
5.線程不安全
6.JDK1.8 HashMap 采用 “數(shù)組 + 鏈表 + 紅黑樹” 的混合結(jié)構(gòu),平衡效率與哈希沖突問(wèn)題
在使用上可以參考下面的代碼:
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class HashMapUsage {
public static void main(String[] args) {
// 1. 初始化(指定初始容量可減少擴(kuò)容次數(shù))
Map<String, Integer> scoreMap = new HashMap<>(16); // 初始容量16
// 2. 添加鍵值對(duì)
scoreMap.put("張三", 90);
scoreMap.put("李四", 85);
scoreMap.put("王五", 95);
scoreMap.put("張三", 92); // 鍵重復(fù),覆蓋舊值(張三的分?jǐn)?shù)變?yōu)?2)
// 3. 獲取值
int lisiScore = scoreMap.get("李四"); // 85
System.out.println("李四的分?jǐn)?shù):" + lisiScore);
// 4. 判斷是否包含鍵/值
boolean hasWangwu = scoreMap.containsKey("王五"); // true
boolean hasScore90 = scoreMap.containsValue(90); // false(已被覆蓋)
// 5. 遍歷(推薦 entrySet() 方式,效率最高)
Set<Map.Entry<String, Integer>> entries = scoreMap.entrySet();
for (Map.Entry<String, Integer> entry : entries) {
System.out.println(entry.getKey() + ":" + entry.getValue());
}
// 6. 刪除元素
scoreMap.remove("王五"); // 刪除王五的鍵值對(duì)
// 7. 其他操作
System.out.println("元素?cái)?shù)量:" + scoreMap.size()); // 2(張三、李四)
scoreMap.clear(); // 清空所有元素
System.out.println("是否為空:" + scoreMap.isEmpty()); // true
}
}注意:
作為鍵的對(duì)象(如自定義類)必須重寫 hashCode() 和 equals() 方法,否則會(huì)導(dǎo)致:
hashCode() 未重寫:不同對(duì)象可能計(jì)算出相同哈希值(哈希沖突加劇),或相同對(duì)象計(jì)算出不同哈希值(無(wú)法正確查找)。
equals() 未重寫:哈希值相同的不同對(duì)象無(wú)法被識(shí)別為不同鍵(導(dǎo)致誤判為重復(fù)鍵)。
1.5 LinkedHashMap的使用
LinkedHashMap 是 HashMap 的子類,它在哈希表的基礎(chǔ)上,通過(guò)雙向鏈表維護(hù)了鍵值對(duì)的插入順序或訪問(wèn)順序,兼具哈希表的高效查找能力和鏈表的有序性。
1.可以存放鍵值對(duì)
2.鍵不允許重復(fù)存放,依據(jù)是添加進(jìn)來(lái)的元素的鍵 hashcode()和equals()
3.可以保證存取順序一致性,由于多了一條鏈表可以維系存進(jìn)來(lái)的順序
4.允許存放null鍵、null值
5.線程不安全
LinkedHashMap 在 HashMap 的基礎(chǔ)上,給每個(gè)節(jié)點(diǎn)(Entry)增加了兩個(gè)指針:before(前一個(gè)節(jié)點(diǎn))和 after(后一個(gè)節(jié)點(diǎn)),形成雙向鏈表:
參考代碼如下,比起HashMap保證了存取的一致性:
import java.util.LinkedHashMap;
import java.util.Map;
public class LinkedHashMapDemo {
public static void main(String[] args) {
Map<String, String> map = new LinkedHashMap<>();
map.put("name", "張三");
map.put("age", "20");
map.put("gender", "男");
// 遍歷順序與插入順序一致
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println(entry.getKey() + ":" + entry.getValue());
}
// 輸出:
// name:張三
// age:20
// gender:男
}
}LinkedHashMap 是 “有序版的 HashMap”,在保留哈希表高效操作的同時(shí),通過(guò)雙向鏈表實(shí)現(xiàn)了順序維護(hù)。
1.6TreeMap的使用
TreeMap 是 Java 集合框架中基于紅黑樹(Red-Black Tree) 實(shí)現(xiàn)的 Map 接口實(shí)現(xiàn)類,其核心特性是按鍵(Key)的自然順序或自定義順序進(jìn)行排序,適合需要有序鍵值對(duì)的場(chǎng)景。
1.可以存放鍵值對(duì)
2.鍵不允許重復(fù)存放,依據(jù)是添加進(jìn)來(lái)的元素的鍵 compareTo()返回0
3.存取順序不一致,但是會(huì)對(duì)鍵進(jìn)行排序
3.1 要么元素自身具備比較性,implements Comparable, 重寫compareTo()
3.2 要么集合容器自身具備比較性,在構(gòu)造方法中,傳入Comparator比較器,重寫compare()
4.不允許存放null鍵,可以存放null值
5.線程不安全
如通過(guò)自然順序比較則代碼如下;
import java.util.TreeMap;
import java.util.Map;
public class TreeMapNaturalOrder {
public static void main(String[] args) {
// 鍵為 Integer(已實(shí)現(xiàn) Comparable,默認(rèn)按數(shù)字升序排序)
TreeMap<Integer, String> numMap = new TreeMap<>();
numMap.put(3, "Three");
numMap.put(1, "One");
numMap.put(2, "Two");
numMap.put(5, "Five");
numMap.put(4, "Four");
System.out.println("按數(shù)字升序排序:");
for (Map.Entry<Integer, String> entry : numMap.entrySet()) {
System.out.println(entry.getKey() + " → " + entry.getValue());
}
// 鍵為 String(已實(shí)現(xiàn) Comparable,默認(rèn)按字典序排序)
TreeMap<String, Integer> strMap = new TreeMap<>();
strMap.put("banana", 3);
strMap.put("apple", 5);
strMap.put("orange", 2);
System.out.println("\n按字符串字典序排序:");
for (Map.Entry<String, Integer> entry : strMap.entrySet()) {
System.out.println(entry.getKey() + " → " + entry.getValue());
}
}
}當(dāng)需要自定義排序規(guī)則(如降序、按字段排序等),可通過(guò) Comparator 實(shí)現(xiàn)。
import java.util.TreeMap;
import java.util.Comparator;
import java.util.Map;
// 自定義類:Person(包含姓名和年齡)
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public int getAge() { return age; }
public String getName() { return name; }
@Override
public String toString() {
return name + "(" + age + ")";
}
}
public class TreeMapCustomOrder {
public static void main(String[] args) {
// 自定義比較器:按 Person 的年齡降序排序
Comparator<Person> ageDescComparator = (p1, p2) ->
Integer.compare(p2.getAge(), p1.getAge()); // 降序(p2 - p1)
// 創(chuàng)建 TreeMap 時(shí)傳入自定義比較器
TreeMap<Person, String> map = new TreeMap<>(ageDescComparator);
map.put(new Person("張三", 20), "學(xué)生");
map.put(new Person("李四", 30), "老師");
map.put(new Person("王五", 25), "工程師");
System.out.println("按年齡降序排序:");
for (Map.Entry<Person, String> entry : map.entrySet()) {
System.out.println(entry.getKey() + " → " + entry.getValue());
}
}
}TreeMap 的核心價(jià)值在于按鍵排序和高效的范圍操作,其紅黑樹結(jié)構(gòu)保證了有序性和穩(wěn)定的性能。使用時(shí)需確保鍵可比較(通過(guò) Comparable 或 Comparator),并注意其不支持 null 鍵和非線程安全的特性。
第二章 Set接口
java.util.Set接口和java.util.List接口一樣,同樣繼承自Collection接口,它與Collection接口中的方法基本一致,并沒有對(duì)Collection接口進(jìn)行功能上的擴(kuò)充,只是比Collection接口更加嚴(yán)格了。與List接口不同的是,Set接口都會(huì)以某種規(guī)則保證存入的元素不出現(xiàn)重復(fù)。
Set集合有多個(gè)子類,這里我們介紹其中的java.util.HashSet、java.util.LinkedHashSet
其實(shí)對(duì)于Set 集合本質(zhì)上可以理解為 Map 中 “鍵(Key)的集合
2.1 HashSet集合
HashSet 是 Java 集合框架中基于 HashMap 實(shí)現(xiàn)的 Set 接口實(shí)現(xiàn)類,其核心特性是存儲(chǔ)唯一元素(不允許重復(fù)) 且不保證元素順序,是日常開發(fā)中最常用的 Set 實(shí)現(xiàn)類之一。
使用示例:
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class HashSetDemo {
public static void main(String[] args) {
// 創(chuàng)建 HashSet 實(shí)例
Set<String> set = new HashSet<>();
// 1. 添加元素(重復(fù)元素不會(huì)被添加)
set.add("apple");
set.add("banana");
set.add("apple"); // 重復(fù)元素,添加失敗
set.add(null); // 允許添加一個(gè)null
set.add(null); // 重復(fù)null,添加失敗
// 2. 遍歷元素(順序不固定)
System.out.println("增強(qiáng)for遍歷:");
for (String s : set) {
System.out.println(s);
}
System.out.println("\n迭代器遍歷:");
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
// 3. 其他常用操作
System.out.println("\n是否包含banana:" + set.contains("banana")); // true
System.out.println("元素?cái)?shù)量:" + set.size()); // 3(apple、banana、null)
set.remove("banana"); // 刪除元素
System.out.println("刪除后元素:" + set); // [null, apple](順序可能不同)
set.clear(); // 清空集合
System.out.println("清空后是否為空:" + set.isEmpty()); // true
}
}當(dāng)自定義類作為 HashSet 元素時(shí),必須同時(shí)重寫 hashCode() 和 equals() 方法,否則會(huì)導(dǎo)致重復(fù)元素?zé)o法被識(shí)別。
2.2 LinkedHashSet集合
LinkedHashSet 是 HashSet 的子類,底層基于 LinkedHashMap 實(shí)現(xiàn),它在保證元素唯一性的同時(shí),還能維護(hù)元素的插入順序,兼具 HashSet 的高效性和鏈表的有序性。
使用示例:
import java.util.LinkedHashSet;
import java.util.Set;
public class LinkedHashSetDemo {
public static void main(String[] args) {
Set<String> set = new LinkedHashSet<>();
// 添加元素(重復(fù)元素不生效)
set.add("張三");
set.add("李四");
set.add("王五");
set.add("張三"); // 重復(fù),不添加
// 遍歷順序與插入順序一致
System.out.println("遍歷元素:");
for (String name : set) {
System.out.println(name);
}
// 其他操作(與 HashSet 一致)
System.out.println("\n是否包含李四:" + set.contains("李四")); // true
set.remove("王五");
System.out.println("刪除后元素:" + set); // [張三, 李四]
}
}2.3 TreeSet集合
TreeSet 是 Java 集合框架中基于 TreeMap 實(shí)現(xiàn)的 Set 接口實(shí)現(xiàn)類,其核心特性是元素唯一且有序,排序規(guī)則基于元素的自然順序或自定義比較器,適合需要對(duì)元素進(jìn)行排序和去重的場(chǎng)景。
1. 自然排序
元素類型需實(shí)現(xiàn) java.lang.Comparable 接口,并重寫 compareTo() 方法定義排序規(guī)則(如 Integer、String 等內(nèi)置類已實(shí)現(xiàn))。
import java.util.TreeSet;
import java.util.Set;
public class TreeSetNaturalSort {
public static void main(String[] args) {
// 元素為 Integer(已實(shí)現(xiàn) Comparable,默認(rèn)按數(shù)字升序)
Set<Integer> set = new TreeSet<>();
set.add(3);
set.add(1);
set.add(2);
set.add(3); // 重復(fù)元素,不添加
System.out.println("自然排序(升序):" + set); // [1, 2, 3]
}
}2. 自定義排序
創(chuàng)建 TreeSet 時(shí)傳入 java.util.Comparator 接口實(shí)現(xiàn)類,指定自定義排序規(guī)則(如降序、按對(duì)象字段排序)。
import java.util.TreeSet;
import java.util.Comparator;
public class TreeSetCustomSort {
public static void main(String[] args) {
// 自定義比較器:按整數(shù)降序
Comparator<Integer> descComparator = Comparator.reverseOrder();
TreeSet<Integer> set = new TreeSet<>(descComparator);
set.add(3);
set.add(1);
set.add(2);
System.out.println("自定義排序(降序):" + set); // [3, 2, 1]
}
}到此這篇關(guān)于Java集合框架Set&Map的文章就介紹到這了,更多相關(guān)java集合框架set map內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java如何從地址串中解析提取省市區(qū)(完美匹配中國(guó)所有地址)
這篇文章主要給大家介紹了關(guān)于java如何從地址串中解析提取省市區(qū)的相關(guān)資料,通過(guò)這個(gè)方法可以完美匹配中國(guó)所有地址,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-07-07
java實(shí)現(xiàn)兩臺(tái)服務(wù)器間文件復(fù)制的方法
這篇文章主要介紹了java實(shí)現(xiàn)兩臺(tái)服務(wù)器間文件復(fù)制的方法,是對(duì)單臺(tái)服務(wù)器上文件復(fù)制功能的升級(jí)與改進(jìn),具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-01-01
java中json-diff簡(jiǎn)單使用及對(duì)象是否一致詳解
這篇文章主要為大家介紹了java中json-diff簡(jiǎn)單使用及對(duì)象是否一致對(duì)比詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03
Classloader隔離技術(shù)在業(yè)務(wù)監(jiān)控中的應(yīng)用詳解
這篇文章主要為大家介紹了Classloader隔離技術(shù)在業(yè)務(wù)監(jiān)控中的應(yīng)用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08
MyBatisPlus代碼生成器實(shí)踐(自己二次封裝)
這段描述主要講解了如何配置MybatisPlus以生成代碼,并強(qiáng)調(diào)了官方文檔的重要性,同時(shí)提到了.xml文件的放置位置以及自動(dòng)掃描的功能,適合對(duì)MybatisPlus感興趣的開發(fā)者閱讀2026-05-05
kafka消費(fèi)不到數(shù)據(jù)的排查過(guò)程
這篇文章主要介紹了kafka消費(fèi)不到數(shù)據(jù)的排查過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02

