Map 集合
认识 Map 集合
-
Map 集合称为双列集合,格式 { key1 = value1, key2 = value2, key3 = value3e},它也被称为"键值对集合"
-
Map 集合的所有键是不允许重复的,但值可以重复,键和值是一一对应的,每一个键只能对应自己的值
Map 集合体系
特点:Map 系列集合的特点都是由键决定的,值只是一个附属品,值是不做要求的
- HashMap:无序、不重复、无索引(用得最多)
- LinkedHashMap:有序、不重复、无索引
- TreeMap:按照大小默认升序排序,不重复,无索引
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;public class Test {public static void main(String[] args) {
// Map<String, Integer> map = new HashMap<>();Map<String, Integer> map = new LinkedHashMap<>(); // 有序、不重复、无索引map.put("手表", 66);map.put("手表", 100); // 后面重复的数据会覆盖前面的数据map.put("手机", 2);map.put("Java", 2);map.put(null, null);System.out.println(map); // {手表=100, 手机=2, Java=2, null=null}Map<Integer, String> map1 = new TreeMap<>(); // 可排序、不重复、无索引map1.put(25, "Java");map1.put(31, "MySQL");map1.put(17, "Python");System.out.println(map1); // {17=Python, 25=Java, 31=MySQL}}
}
Map 集合常用方法
Map 集合是双列集合的祖宗,它的功能是全部双列集合都可以继承过来使用的
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;public class Test {public static void main(String[] args) {// 1. 添加元素Map<String, Integer> map = new HashMap<>();map.put("手表", 66);map.put("手表", 100);map.put("手机", 2);map.put("Java", 2);map.put(null, null);System.out.println(map);// {手表=100, 手机=2, Java=2, null=null}// 2. 获取集合大小System.out.println(map.size());// 3. 清空集合
// map.clear();// 4. 判断是否为空System.out.println(map.isEmpty());// 5. 根据键获取对应值System.out.println(map.get("手表")); // 100// 6. 根据键删除整个元素(删除键会返回键的值)System.out.println(map.remove("手表")); // 100// 7. 判断是否包含某个键System.out.println(map.containsKey("手表"));// 8. 判断是否包含某个值System.out.println(map.containsValue(2));// 9. 获取Map集合的全部键Set<String> keys = map.keySet();System.out.println(keys); // [null, Java, 手机]// 10. 获取Map集合的全部值Collection<Integer> values = map.values();System.out.println(values); // [null, 2, 2]// 11. 把其他Map集合的数据,导入到自己集合中来Map<String, Integer> map1 = new HashMap<>();map1.put("java1", 10);map1.put("java2", 20);Map<String, Integer> map2 = new HashMap<>();map2.put("java3", 30);map2.put("java4", 40);map1.putAll(map2); // 把map2集合中的元素全部导入到map1System.out.println(map2); // {java4=40, java3=30}System.out.println(map1); // {java4=40, java3=30, java2=20, java1=10}}
}
Map 集合的遍历
- 方式一:键找值 ( 普通的方法 )
import java.util.HashMap;
import java.util.Map;
import java.util.Set;public class Test {public static void main(String[] args) {// 准备一个Map集合Map<String, Double> map = new HashMap<>();map.put("Jack", 168.5);map.put("Tony", 178.8);map.put("Peter", 158.9);map.put("Tomato", 180.7);System.out.println(map);// {Tony=178.8, Peter=158.9, Jack=168.5, Tomato=180.7}// 1. 获取Map集合的所有键Set<String> keys = map.keySet();System.out.println(keys); // [Tony, Peter, Jack, Tomato]// 2. 遍历所有的键,根据键获取其对应的值for (String key : keys) {System.out.println(key + " <=====> " + map.get(key));}// 运行结果
// Tony <=====> 178.8
// Peter <=====> 158.9
// Jack <=====> 168.5
// Tomato <=====> 180.7}
}
- 方式二:键值对 (把"键值对"看成一个整体进行遍历)
import java.util.HashMap;
import java.util.Map;
import java.util.Set;public class Test {public static void main(String[] args) {// 准备一个Map集合Map<String, Double> map = new HashMap<>();map.put("Jack", 168.5);map.put("Tony", 178.8);map.put("Peter", 158.9);map.put("Tomato", 180.7);System.out.println(map);// {Tony=178.8, Peter=158.9, Jack=168.5, Tomato=180.7}// 1. 获取Map集合提供的entrySet方法,把Map集合转成键值对类型的Set集合Set<Map.Entry<String, Double>> entries = map.entrySet();
// entries 相当于是 => [(Tony=178.8), (Peter=158.9), (Jack=168.5), (Tomato=180.7)]for (Map.Entry<String, Double> entry : entries) {System.out.println((entry.getKey() + " <=====> " + entry.getValue()));}// 运行结果
// Tony <=====> 178.8
// Peter <=====> 158.9
// Jack <=====> 168.5
// Tomato <=====> 180.7}
}
- 方式三:Lambda ( JDK 8 开始之后的新技术 )
import java.util.HashMap;
import java.util.Map;public class Test {public static void main(String[] args) {// 准备一个Map集合Map<String, Double> map = new HashMap<>();map.put("Jack", 168.5);map.put("Tony", 178.8);map.put("Peter", 158.9);map.put("Tomato", 180.7);System.out.println(map);// {Tony=178.8, Peter=158.9, Jack=168.5, Tomato=180.7}// lambda 表达式map.forEach((k, v) -> {System.out.println(k + " <=====> " + v);});// 运行结果
// Tony <=====> 178.8
// Peter <=====> 158.9
// Jack <=====> 168.5
// Tomato <=====> 180.7}
}
HashMap
特点:无序、不重复、无索引(用得最多)
底层原理:HashMap 跟 HashSet 的底层原理是一模一样的,都是基于哈希表实现的;实际上,原来学的 Set 系列集合的底层就是基于 Map 实现的,只是 Set 集合中的元素只要键数据,不要值数据而已。
LinkedHashMap
特点:有序、不重复、无索引
底层原理:底层数据结构依然是基于哈希表实现的,只是每个元素值对元素又额外的多了一个双链表的机制记录元素顺序(保证有序);实际上,原来学的 LinkedHashSet 集合的底层原理就是 LinkedHashMap 。
TreeMap
特点:按照大小默认升序排序,不重复,无索引
底层原理:TreeMap 跟TreeSet 集合的底层原理是一样的,都是基于红黑树实现排序。
// TreeMap 集合同样也支持指定比较规则import java.util.Comparator;
import java.util.Map;
import java.util.TreeMap;public class Test {public static void main(String[] args) {// 未简化模式
// Map<Student, String> map = new TreeMap<>(new Comparator<Student>() {
// @Override
// public int compare(Student o1, Student o2) {
// return Double.compare(o1.getScore(), o2.getScore()); // 升序
// }
// });// lambda 简化模式Map<Student, String> map = new TreeMap<>((o1, o2) -> Double.compare(o1.getScore(), o2.getScore());map.put(new Student("Jack", 66.5), "打篮球");map.put(new Student("Peter", 96.0), "敲代码");map.put(new Student("Tony", 86.5), "唱歌");System.out.println(map);// {Student{name='Jack', score=66.5}=打篮球, Student{name='Tony', score=86.5}=唱歌, Student{name='Peter', score=96.0}=敲代码}}
}class Student {private String name;private double score;@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", score=" + score +'}';}public Student() {}public Student(String name, double score) {this.name = name;this.score = score;}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getScore() {return score;}public void setScore(double score) {this.score = score;}
}
集合的嵌套(补充)
通过一个案例,快速理解与使用:
import java.util.*;public class Test {public static void main(String[] args) {/*** 要求用集合实现:* 江苏省 = "南京市", "扬州市", "苏州市", "无锡市", "常州市"* 湖北省 = "武汉市", "孝感市", "十堰市", "宜昌市", "鄂州市"* 河北省 = "石家庄", "唐山市", "邢台市", "保定市", "张家口"*/// 1. 创建外层集合Map<String, List<String>> map = new HashMap<>();// 2. 创建内层集合 + 内层集合填充数据List<String> lst1 = new ArrayList<>();Collections.addAll(lst1, "南京市", "扬州市", "苏州市", "无锡市", "常州市");// 3. 外层集合填充数据map.put("江苏省", lst1);// 其他部分List<String> lst2 = new ArrayList<>();Collections.addAll(lst2, "武汉市", "孝感市", "十堰市", "宜昌市", "鄂州市");map.put("湖北省", lst2);List<String> lst3 = new ArrayList<>();Collections.addAll(lst3, "石家庄", "唐山市", "邢台市", "保定市", "张家口");map.put("河北省", lst3);// 展示map.forEach((place, city) -> {System.out.println(place + ":" + city);});// 运行结果
// 江苏省:[南京市, 扬州市, 苏州市, 无锡市, 常州市]
// 湖北省:[武汉市, 孝感市, 十堰市, 宜昌市, 鄂州市]
// 河北省:[石家庄, 唐山市, 邢台市, 保定市, 张家口]}
}