一、雙列集合:
Map<K,V> 集合的特點:K用來限制鍵的類型,V用來限制值的類型
1.Map集合存儲元素是以鍵值對的形式存儲的,每一個鍵值對都有鍵和值
2.Map集合的鍵是唯一,值可以重複,如果鍵重複了,那麼值就會被覆寫
3.根據鍵來取值
Map集合子類:
- HashMap<K,V> 存儲資料采用的哈希表結構,元素的存取順序不能保證一緻
由于要保證鍵的唯一,不重複,需要重寫鍵的hashCode方法,equals方法
- LinkedHashMap<K,V> hashMap下的子類,存儲資料采用的是哈希表結構 + 連結清單結構
通過連結清單結構可以保證鍵值對的存取順序一緻
通過哈希表結構可以保證鍵的唯一,不重複,
需要重寫鍵的hashCode方法,equals方法
- TreeMap<K,V>TreeMap集合和Map相比沒有特有的功能,底層的資料結構都是紅黑樹
可以對元素的鍵進行排序,排序方式由兩種:自然排序和比較器排序
二、Map的常用方法
這些是Map集合常用的方法
- public V put(K key, V value) 把指定的鍵與指定的值添加到Map集合中
- public V remove(Object key) 把指定的鍵所對應的鍵值對元素 在Map集合中删除,傳回被删除的元素的值
- public V get(Object key) 根據指定的鍵,在Map集合中擷取對應的值
- public boolean containsKey(Object key) 判斷該集合中是否包含有此鍵
- public boolean containsValue(Object value) 判斷該集合中是否包含有此值
- public Set<K> keySet() 擷取Map集合中所有的鍵,存儲到Set集合中
- public Collection<V> values() 擷取Map集合中所有的值,存儲到Collection集合中
- public Set<Map.Entry<K,V>> entrySet() 擷取到Map集合中所有的鍵值對 對象的集合(Set集合)
- public static interface Map.Entry<K,V> 表示鍵值對對象 --- 把鍵值對包裝成一個對象,該對象類型就是Entry類型
下面是對應方法的代碼示範
// 建立Map集合,限制鍵的類型為String,值的類型為String
Map<String,String> map = new HashMap<>();
// 往map集合中添加鍵值對
map.put("老大","老二");
map.put("大王","小王");
map.put("張二","張三");
System.out.println(map);
// Map集合鍵唯一,如果鍵重複了,值會覆寫
String s1 = map.put("老大","老三");
System.out.println(s1);
System.out.println(map);
// Map集合值可以重複
String s2 = map.put("張一", "張三");
System.out.println(s2);// null
System.out.println(map);
// 删除文章鍵對應的這個鍵值對
String s3 = map.remove("大王");
System.out.println(s3);
System.out.println(map);
// 擷取黃曉明鍵對應的值
String s4 = map.get("老大");
System.out.println(s4);
// 判斷是否包含指定的鍵
boolean flag1 = map.containsKey("老大");
System.out.println(flag1);// true
// 判斷是否包含指定的值
boolean flag2 = map.containsValue("老大");
System.out.println(flag2);// false
// 擷取所有的鍵
Set<String> strings = map.keySet();
System.out.println(strings);
// 擷取所有的值
Collection<String> values = map.values();
System.out.println(values);
// 擷取Map集合中所有的鍵值對對象
Set<Map.Entry<String, String>> entries = map.entrySet();
System.out.println(entries);
輸出結果:
{張二=張三, 老大=老二, 大王=小王}
老二
{張二=張三, 老大=老三, 大王=小王}
null
{張二=張三, 老大=老三, 張一=張三, 大王=小王}
小王
{張二=張三, 老大=老三, 張一=張三}
老三
true
false
[張二, 老大, 張一]
[張三, 老三, 張三]
[張二=張三, 老大=老三, 張一=張三]
三、Map集合的周遊
1.方式一
(1)、擷取Map集合所有的值
(2)、循環周遊Map集合所有的鍵
(3)、在循環中,根據鍵找值
// 建立Map集合,限制鍵的類型為String,值的類型為String
Map<String,String> map = new HashMap<>();
// 往map集合中添加鍵值對
map.put("老大","老二");
map.put("大王","小王");
map.put("張二","張三");
// 方式一:根據鍵找值
// 1.擷取Map集合所有的鍵
Set<String> strings = map.keySet();
// 2.循環周遊Map集合所有的鍵
for (String key : strings) {
// 3.在循環中,根據鍵找值
String value = map.get(key);
System.out.println(key +"=="+value);
}
輸出結果:
張二==張三
老大==老二
大王==小王
2.方式二、
Entry<K,V>接口:簡稱Entry項,表示鍵值對對象,用來封裝Map集合中的鍵值對
Entry<K,V>接口:Map解耦中的内部接口,在外部使用的時候是這樣表示的
Map.Entry<K,V>
Map.Entry<K,V>接口中的API:
- K getKey();擷取鍵值對對象包裝的鍵
- K getValue(); 擷取鍵值對對象包裝的值
周遊步驟:
(1):擷取Map集合中所有的鍵值對 對應的 鍵值對對象 entrySet()方法
(2):循環周遊所有的鍵值對對象
(3):根據鍵值對對象擷取鍵和值
// 建立Map集合,限制鍵的類型為String,值的類型為String
Map<String,String> map = new HashMap<>();
// 往map集合中添加鍵值對
map.put("老大","老二");
map.put("大王","小王");
map.put("張二","張三");
// 方式二:鍵值對對象的形式
// 1.擷取Map集合中所有的鍵值對 對應的 鍵值對對象 entrySet() 方法
Set<Map.Entry<String, String>> entries = map.entrySet();
// 2.循環周遊所有的鍵值對對象
for (Map.Entry<String, String> entry : entries) {
//3.根據鍵值對對象擷取鍵和值
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key +"==" + value);
}
輸出結果:
張二==張三
老大==老二
大王==小王
四、HashMap存儲自定義類型
// 建立要給學生對象
public class Student {
String name;
int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age &&
Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
// 建立HashMap集合,限制鍵的類型為Student,值的類型為String
Map<Student,String> map = new HashMap<>();
// 往集合中添加鍵值對
Student s1 = new Student("張三",15);
Student s2 = new Student("李四",50);
Student s3 = new Student("王五",17);
Student s4 = new Student("趙六",41);
Student s5 = new Student("劉七",19);
Student s6 = new Student("張三",15);
map.put(s1,"北京");
map.put(s2,"上海");
map.put(s3,"深圳");
map.put(s4,"武漢");
map.put(s5,"鄭州");
map.put(s6,"白沙洲");
System.out.println(map);
System.out.println(map.size());
輸出結果:
{Student{name='王五', age=17}=深圳, Student{name='劉七', age=19}=鄭州, Student{name='李四', age=50}=上海, Student{name='張三', age=15}=白沙洲, Student{name='趙六', age=41}=武漢}
5
這裡map集合的長度是5,因為Map集合要保證鍵的唯一,
是以同時給Student存儲兩個張三的話,鍵值會被覆寫,就導緻給map存儲時s1和s6沖突,s6覆寫掉s1的現象
最終結果也如代碼展示一樣,map的大小是5,北京被白沙洲覆寫
五、LinkedHashMap集合
LinkedHashMap:元素存取有序,鍵唯一,值可重複
- 通過連結清單結構保證元素存取有序,順序一緻
- 通過哈希表結構可以保證鍵的唯一,不重複,需要複寫hashCode方法和equals方法
// 建立LinkedHashmap對象,限制鍵的類型為Integer,值的類型為String
LinkedHashMap<Integer,String> map = new LinkedHashMap<>();
// 給集合中存儲一些鍵值
map.put(300,"北京");
map.put(100,"上海");
map.put(600,"太原");
map.put(900,"西安");
map.put(300,"臨汾");
System.out.println(map);
輸出結果:
{300=臨汾, 100=上海, 600=太原, 900=西安}
六、TreeMap集合
TreeMap集合:鍵唯一,值可重複,如果鍵重複了,值會覆寫
- public TreeMap() 根據鍵按照預設規則進行排序
- public TreeMap(Comparator<? super K> comparator) 通過比較器指定規則排序
// 預設規則:升序
TreeMap<Integer,String> map = new TreeMap<>();
map.put(300,"北京");
map.put(100,"上海");
map.put(600,"太原");
map.put(900,"西安");
map.put(300,"臨汾");
System.out.println(map);// {100=上海, 300=臨汾, 600=太原, 900=西安}
// 指定規則:降序
TreeMap<Integer,String> map2 = new TreeMap<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
map2.put(300,"北京");
map2.put(100,"上海");
map2.put(600,"太原");
map2.put(900,"西安");
map2.put(300,"臨汾");
System.out.println(map2);// {900=西安, 600=太原, 300=臨汾, 100=上海}
輸出結果:
{100=上海, 300=臨汾, 600=太原, 900=西安}
{900=西安, 600=太原, 300=臨汾, 100=上海}