目錄
Map介面
Map介面概述
Map介面和Collection介面的不同 ( Collection介面 )
Map介面成員方法
添加功能
洗掉功能
判斷功能
獲取功能
長度功能
Map集合遍歷
方式1:根據鍵找值
方式2:根據鍵值對物件找鍵和值
HashMap類
HashMap類概述
HashMap案例
LinkedHashMap類
TreeMap類
TreeMap類概述
TreeMap案例
Map集合練習案例
HashMap與Hash table的區別
Collections類
Collections類概述
Collections類和Collection的區別
Collections成員方法
Collections中的方法能執行緒不安全的集合變成安全的
Map介面

Map介面概述
a.將鍵映射到值的物件
b.一個映射不能包含重復的鍵
c.每個鍵最多只能映射到一個值
Map介面和Collection介面的不同 ( Collection介面 )
a.Map是雙列的,Collection是單列的
b.Map的鍵唯一,Collection的子體系Set是唯一的
c.Map集合的資料結構值針對鍵有效,跟值無關 Collection集合的資料結構是針對元素有效
Map介面成員方法
添加功能
V put(K key,V value) 將指定的值與該映射中的指定鍵相關聯
import java.util.HashMap;
import java.util.Map;
public class MapTest1 {
public static void main(String[] args) {
//Map是一個介面,不能實體化,借助子類HashMap來實體化
Map<String, String> map = new HashMap<>();
//V put(K key,V value) 將指定的值與該映射中的指定鍵相關聯
map.put("充電器","手機");
map.put("電腦","滑鼠");
System.out.println(map.put("電腦","鍵盤")); //如果插入的鍵一樣,值會被覆寫,回傳的是被覆寫的值
System.out.println(map);
}
}

洗掉功能
V remove(Object key) 如果存在(從可選操作),從該Map中洗掉一個鍵的映射
map.remove("電腦");
void clear() 從該Map中洗掉所有的映射(可選操縱)
map.clear();
判斷功能
boolean containsKey(Object key) 如果此映射包含指定鍵的映射,則回傳true
//boolean containsKey(Object key) 如果此映射包含指定鍵的映射,則回傳true
System.out.println(map);
System.out.println(map.containsKey("充電器"));

boolean containsValue(Object value) 如果此Map將一個或多個鍵映射到指定的值,則回傳true,
map.containsValue("手機")
boolean isEmpty() 如果此Map不包含鍵值映射,則回傳true
map.isEmpty();//判斷是否有鍵值對,有回傳true,無false
獲取功能
V get(Object key) 回傳指定鍵所映射的值,或null如果此映射包含該鍵的映射
System.out.println(map.get("充電器"));

Set<K> keySet() 回傳此Map中包含的鍵的Set試圖
Set<String> set=map.keySet();
//遍歷
for (String s:set){
System.out.println(s);
}

Collection<V> values() 回傳此Map中包含的值的Collection視圖
//Collection<V> values() 回傳此Map中包含的值的Collection視圖
Collection<String> value =map.values();
for (String s :value){
System.out.println(s);
}

Set<Map.Entry<K,V>> entrySet() 獲取Map中所有的元素,元素的類組成是由一個鍵和一個值組成
//Set<Map.Entry<K,V>> entrySet() 獲取Map中所有的元素,元素的類組成是由一個鍵和一個值組成
Set<Map.Entry<String, String>> entries = map.entrySet();
for (Map.Entry<String, String> s :entries){
System.out.println(s);
}

長度功能
int size() 回傳此Map中鍵值映射的數量
int size = map.size();
System.out.println(size); //結果為2,取決于里面有多少個鍵值對
Map集合遍歷
方式1:根據鍵找值
獲取所有鍵的集合
遍歷鍵的集合,獲取到每一個鍵
根據鍵找值
例:
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MapTest2 {
public static void main(String[] args) {
//創建集合物件
Map<Integer, String> map = new HashMap<>();
//向集合添加元素
map.put(11,"qew");
map.put(23,"qew");
map.put(33,"sfs");
map.put(22,"asf");
//遍歷
Set<Integer> set = map.keySet(); //獲取到每一個鍵
for (Integer s:set){
String s1 = map.get(s); //獲取到每一個鍵對應的值
System.out.println(s+":"+s1);
}
}
}
方式2:根據鍵值對物件找鍵和值
獲取所有鍵值對物件的集合
遍歷鍵值對物件的集合,獲取到每一個鍵值對物件
根據鍵值對物件找鍵和值
//創建集合物件
Map<Integer, String> map = new HashMap<>();
//向集合添加元素
map.put(4,"rte");
map.put(23,"d234");
map.put(5,"e121");
map.put(75,"qee");
map.put(22,"fa");
//遍歷
Set<Map.Entry<Integer, String>> entries = map.entrySet(); //獲取到鍵值對集合
for (Map.Entry<Integer, String> s:entries){
Integer key = s.getKey(); //獲取到鍵值對對應的鍵
String value = s.getValue(); //獲取到鍵值對對應的值
System.out.println(key+":"+value);
}

HashMap類
HashMap類概述
鍵是哈希表結構,可以保證鍵的唯一性
HashMap案例
HashMap<String,String>
HashMap<Integer,String>
上面兩個跟Map集合中的案例一樣,重點說下面的
HashMap<String,Student>
首先封裝一個學生類
public class Student {
private String name;
private int age;
public Student() {}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
在創建集合添加學生物件測驗
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class HashMapTest1 {
public static void main(String[] args) {
//創建集合物件
HashMap<String, Student> hashMap = new HashMap<>();
//創建學生物件
Student s1 =new Student("student1",23);
Student s2 =new Student("student2",14);
Student s3 =new Student("student3",17);
Student s4 =new Student("student4",25);
Student s5 =new Student("student5",23);
//向集合添加元素
hashMap.put("sas",s1);
hashMap.put("qwe",s2);
hashMap.put("fsa",s3);
hashMap.put("ddd",s4);
hashMap.put("qca",s5);
//遍歷
Set<Map.Entry<String, Student>> entries = hashMap.entrySet();
for (Map.Entry<String, Student> s:entries){
String key = s.getKey();
Student value = s.getValue(); //也可以呼叫student中的get方法把名字,年齡獲取出來遍歷
System.out.println(key+":"+value);
}
}
}

HashMap<Student,String>
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class HashMapTest2 {
public static void main(String[] args) {
//創建集合物件
HashMap<Student, String> hashMap = new HashMap<>();
//創建學生物件
Student s1=new Student("qa",23);
Student s2=new Student("ea",25);
Student s3=new Student("fa",22);
Student s4=new Student("da",15);
Student s5=new Student("qa",23);
//向集合添加元素
hashMap.put(s1,"111");
hashMap.put(s2,"222");
hashMap.put(s3,"333");
hashMap.put(s4,"444");
hashMap.put(s5,"555");
//遍歷
Set<Map.Entry<Student, String>> entries = hashMap.entrySet();
for (Map.Entry<Student, String> s:entries){
Student key = s.getKey();
String value = s.getValue();
System.out.println(key+":"+value);
}
}
}

從輸出結果能發現,key有重復的物件,這違背了map中鍵是唯一的定義,原因是添加元素的put方法的原始碼涉及到hashCode()方法和equals()方法來判斷元素是否重復(在Hash Set類中說過,Set介面 ),而我們創建做為key的自定義Student類中沒有重寫hashCode()方法和equals()方法,所以只能呼叫Object類中的equals方法來比較地址值,每一個學生物件都是new出來的,地址值固然不一樣,
解決方法:在Student類中重寫hashCode()方法和equals()方法
@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);
}

這樣key就不會重復了
LinkedHashMap類
LinkedHashMap類概述
a.繼承自HashMap類,實作了Map介面
b.Map 介面的哈希表和鏈接串列實作,具有可預知的迭代順序,
哈希表保證元素的唯一,保證key是唯一
鏈表保證有序 (存盤和取出的順序一致)
例:
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
public class LinkedHashMapTest1 {
public static void main(String[] args) {
//創建集合物件
LinkedHashMap<String, String> map = new LinkedHashMap<>();
//向集合添加元素
map.put("s1","qqw");
map.put("s2","q232");
map.put("s3","q211");
map.put("s4","d23");
map.put("s1","dsa");
//遍歷
Set<Map.Entry<String, String>> entries = map.entrySet();
for (Map.Entry<String, String> s:entries){
String key = s.getKey();
String value = s.getValue();
System.out.println(key+":"+value);
}
}
}

從結果可以看出重復的key的值被覆寫了,并且輸出的順序就是存放的順序
TreeMap類
TreeMap類概述
鍵是紅黑樹結構,可以保證鍵的排序和唯一性
TreeMap案例
HashMap<String,String>
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
public class TreeMapTest1 {
public static void main(String[] args) {
//創建集合物件
TreeMap<String, String> map = new TreeMap<>();
//向集合添加元素
map.put("HashSet","Set介面");
map.put("TreeSet","Set介面");
map.put("LinkedHashSet","Set介面");
map.put("HashMap","Map介面");
map.put("HashMap","Map介面");
//遍歷
Set<Map.Entry<String, String>> entries = map.entrySet();
for (Map.Entry<String, String> s:entries){
String key = s.getKey();
String value = s.getValue();
System.out.println(key+":"+value);
}
}
}

可以看出結果去重了,而且按key中的首字母排序,因為無參構造走的是自然排序,String類實作了Comparable介面,重寫了ComparaTo方法( TreeSet類中有說過),String中ComparaTo方法比較ASCII碼值,所以按首字母排序,
HashMap<Student,String>
方法一:
首先封裝一個學生類2,跟學生類1一樣的(不加hashCode方法和equals方法)
再創建集合
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
public class TreeMapTest2 {
public static void main(String[] args) {
//創建集合物件
TreeMap<Student2, String> map = new TreeMap<>();
//創建學生物件
Student2 s1 =new Student2("student1",23);
Student2 s2 =new Student2("student2",22);
Student2 s3 =new Student2("student3",23);
Student2 s4 =new Student2("student1",23);
Student2 s5 =new Student2("student4",20);
//向集合添加元素
map.put(s1,"q111");
map.put(s2,"w111");
map.put(s3,"e111");
map.put(s4,"q111");
map.put(s5,"t111");
//遍歷
Set<Map.Entry<Student2, String>> entries = map.entrySet();
for (Map.Entry<Student2, String> s:entries){
Student2 key = s.getKey();
String value = s.getValue();
System.out.println(key+":"+value);
}
}
}
然后到這一步你會報錯,因為這里走的還是無參構造,自然排序,所創建的Stuent2類沒有實作Comparable介面,而自然排序這個介面中有一個向下轉型,所以會型別轉換例外報錯(具體跟TreeSet類中一 樣 Set介面 )

解決方法:創建的Student2類需實作Comparable介面,并重寫介面的ComparaTo方法,在其中自定義排序方法
public class Student2 implements Comparable<Student2> {
private String name;
private int age;
public Student2() {
}
public Student2(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Student2 o) {
//比較年齡是否一樣
int i1=o.age-this.age;
//年齡一樣,姓名不一定一樣
int i2= i1==0 ? o.name.compareTo(this.name):i1;
return i2;
}
}

可以看出結果去重且按自定義方法排序(按年齡)
方法二:
當然,如果你不想改動學生類,那就走有參構造方法,也就是比較器排序
此時學生類是最初的封裝狀態,不需要修改,只需要在創建物件時修改就可以了,這里采用匿名內部類的方式,直接在創建物件時實作Comparato介面,
//創建集合物件
TreeMap<Student2, String> map = new TreeMap<>(new Comparator<Student2>() { //匿名內部類
@Override
public int compare(Student2 o1, Student2 o2) {
//比較年齡是否一樣
int i1 = o1.getAge() - o2.getAge();
//年齡一樣,姓名不一定一樣
int i2 = i1 == 0 ? o1.getName().compareTo(o2.getName()) : i1;
return i2;
}
});
Map集合練習案例
例1:"aababcabcdabcde",獲取字串中每一個字母出現的次數要求結果:a(5)b(4)c(3)d(2)e(1)
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
public class MapTest4 {
public static void main(String[] args) {
//創建字串物件
String s="aababcabcdabcde";
//創建集合物件
TreeMap<Character, Integer> map = new TreeMap<>();
char[] chars = s.toCharArray(); //轉成字符陣列
//遍歷字符陣列
for (Character c : chars) {
Integer integer = map.get(c); //用每一個字符當作鍵去找值
if (integer == null) { //如果輸出值為null,表示集合中沒有這個鍵,添加這個鍵并賦值1;
map.put(c, 1);
} else { //如果輸出不為null,表示集合中有這個鍵,賦值回傳的值value+1,回傳覆寫到集合中
integer++;
map.put(c, integer);
}
}
//遍歷集合
Set<Map.Entry<Character, Integer>> entries = map.entrySet();
for (Map.Entry<Character, Integer> e:entries){
Character key = e.getKey();
Integer value = e.getValue();
System.out.print(key+"("+value+")");
}
}
}

例2:ArrayList集合嵌套HashMap集合
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MapTest5 {
public static void main(String[] args) {
//創建ArrayList集合物件
ArrayList<HashMap<String, String>> list = new ArrayList<>();
//創建2個HashMap集合,并添加元素
HashMap<String, String> map1 = new HashMap<>();
map1.put("user1","qwq");
map1.put("user2","q33q");
HashMap<String, String> map2 = new HashMap<>();
map2.put("user3","q3we");
map2.put("user4","aa");
//把HashMap集合添加進入ArrayList集合
list.add(map1);
list.add(map2);
//遍歷ArrayList集合
for (HashMap<String, String> s:list){
//遍歷HashMap集合
Set<Map.Entry<String, String>> entries = s.entrySet();
for (Map.Entry<String, String> m:entries){
String key = m.getKey();
String value = m.getValue();
System.out.println(key+":"+value);
}
}
}
}

HashMap與Hash table的區別
a.Hash Map和Hash table它們存盤的都是一個個的鍵值對
b.Hash Map中允許key,value為null,而Hash table不允許
c.Hashtable是執行緒安全的,HashMap是不安全的
Collections類
Collections類概述
針對集合操作 的工具類
Collections類和Collection的區別
a.Collection是單列集合的頂層介面,有兩大子類介面:List介面和Set介面
b.Collections是一個針對于集合操作的工具類,可以對集合進行排序,還有查找(二分查找)
Collections成員方法
public static <T> void sort(List<T> list) 集合排序
import java.util.ArrayList;
import java.util.Collections;
public class CollectionsTest1 {
public static void main(String[] args) {
//創建集合物件
ArrayList<Integer> list = new ArrayList<>();
//向集合添加元素
list.add(54);
list.add(23);
list.add(123);
list.add(42);
list.add(32);
list.add(24);
//public static <T> void sort(List<T> list) 排序
System.out.println("原集合:"+list);
Collections.sort(list);
System.out.println("排序后:"+list);
}
}

public static <T> int binarySearch(List<?> list,T key) 二分查找,回傳索引
System.out.println("原集合:"+list);
int i = Collections.binarySearch(list, 123);
System.out.println(i);

public static <T> T max(Collection<?> coll) 集合中最大值
Integer max = Collections.max(list);
System.out.println(max); //123
public static void reverse(List<?> list) 反轉
System.out.println("原集合:"+list);
Collections.reverse(list);
System.out.println("反轉后:"+list);

public static void shuffle(List<?> list) 隨機置換(隨機排序)
System.out.println("原集合:"+list);
Collections.shuffle(list);
System.out.println("隨機置換后:"+list);

Collections中的方法能執行緒不安全的集合變成安全的
例: static <T> List<T> synchronizedList(List<T> list) (還有很多,不一一舉例了)
回傳由指定串列支持的同步(執行緒安全)串列,
List<Integer> list1 = Collections.synchronizedList(list);
System.out.println(list);
System.out.println(list1);

可以看出兩個list和list1是一樣的,Collections只是給list套了一層,讓它變成安全的,在Vector類中說過雖然Vector是安全的,但Collections工具類比它更好,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/430269.html
標籤:其他

