目录
前言:
①Map集合是一种双列集合,每个元素包含两个数据;
②Map集合的每个元素的格式:key = value(键值对元素);
③Map集合也被称之为键值对集合。
2.Map集合整体格式:
①Collection集合的格式:[元素1,元素2,元素3...]
②Map集合的完整格式:{key1 = value1,key2 = value2,key3 = value3......}
3.Map集合是什么?使用场景是什么?
Map集合是键值对集合;
Map集合非常适合做购物车这样的业务场景;
4.Map集合体系的特点。
①Map集合的特点都是由键决定的。
②Map集合的键是无序,不重复的,无索引的,值不做要求;
③Map集合后面重复的键对应的值会覆盖前面重复键的值。
④Map集合的键值对都可以为null。
5.Map集合实现类特点。
HashMap:元素按照键是无序,不重复,无索引,值不做要求。(与Map体系一致)。
LinkedHashMap:元素按照键是有序,不重复,无索引,值不做要求。
TreeMap:元素按照键是排序,不重复,无索引的,值不做要求。
一、Map集合的遍历方式之一:键找值
先获取Map集合的全部键的Set集合;
遍历键的Set集合,然后通过键提取对应值。
键找值涉及到的API:
二、Map集合的遍历方式之二:键值对
先把Map集合转换成Set集合,Set集合中每个元素都是键值对实体类型;
遍历Set集合,然后提取键以及提取值。
键值对涉及到的API:
三、Map集合的遍历方式之三:Lambda表达式
得益于JDK8开始的新技术Lambda表达式,提供了一种更简单,更直接的遍历集合的方式。
Map结合Lambda遍历的API:
9.代码演示:
/**Map 双列集合,每个元素包含两个数据
* key = value(键值对元素)
* 使用场景:购物车系统
*/
import java.util.*;
import java.util.function.BiConsumer;
/** Map HashMap(LinkedHashMap)、HashTable(Properties)、...(TreeMap)
* 使用最多 :HashMap :无序、不重复、无索引
* 重点掌握: HashMap、LinkHashMap、TreeMap
* LinkHashMap: 有序、不重复、无索引
* TreeMap : 排序,不重复、无索引
* Map集合的特点由键决定 Map集合后面重复的键对应的值会覆盖前面重复键的值
* 键值可以为Null
*/
public class Map_Demo {
public static void main(String[] args) {
//1.创建Map对象,添加元素
Map<String,Integer> map = new HashMap<>();//经典代码
map.put("鸿星尔克",30);
map.put("JAVA书",300);
map.put("Python书",100);
map.put("Html",100);
map.put(null,null);
System.out.println(map);
//2.清空集合
// map.clear();
//3.判断集合是否为空
System.out.println(map.isEmpty());
//4.根据键获取对应的值
Integer key = map.get("Html");
System.out.println(key);
//5.根据键删元素
map.remove("JAVA书");
System.out.println(map);
//6.判断是否包含某个键
System.out.println(map.containsKey("Html"));
System.out.println(map.containsKey("JAVA"));
//7.判断是否包含某个值
System.out.println(map.containsValue(100));
System.out.println("====================================");
//8.获取全部键的集合
Set<String> keys= map.keySet();
System.out.println(keys);
//9.获取全部值的集合
Collection<Integer> values = map.values();
System.out.println(values);
//10.集合的大小
System.out.println(map.size());
//11.合并其他Map集合
Map<String,Integer> map1 = new HashMap<>();
map1.put("JAVA1",70);
map1.put("JAVA2",80);
Map<String,Integer> map2 = new HashMap<>();
map2.put("JAVA3",76);
map2.put("JAVA2",80);
map1.putAll(map2);
System.out.println(map1);
System.out.println("=====================");
Map<String,Integer> maps = new HashMap<>();
maps.put("鸿星尔克",40);
maps.put("JAVA书",30);
maps.put("Python书",20);
maps.put("Html",10);
System.out.println(maps);
//1.键找值 先拿到集合的全部键
Set<String> keyss = maps.keySet();
//2.遍历每一个键,根据键提取值
for (String s : keyss) {
int value = maps.get(s);
System.out.println(s + "====>"+value);
}
System.out.println("---------------------------------------");
//遍历
maps.forEach(new BiConsumer<String, Integer>() {
@Override
public void accept(String s, Integer value) {
System.out.println(s + "====>"+value);
}
});
}
}
10.案例:Map集合:统计投票人数
需求:
某个班级80名学生,现在需要组成秋游活动,班长提供了四个景点依次是(A,B,C,D),每个学生只能选择一个景点,请统计出最终哪个景点想去的人数最多。
分析:
①将80个学生选择的数据拿到程序中去;
②定义Map集合用于存储最终统计的结果;
③遍历80个学生选择的数据,看到Map集合中是否存在,不存在存入"数据=1",存在则其对应值+1.
import java.util.*;
/**
* 统计投票人数
*/
public class Map_Test {
public static void main(String[] args) {
//1.把八十个学生选择的数据拿进来
String[] selects = {"A","B","C","D"};
StringBuilder sb= new StringBuilder();//拼接结果
Random r = new Random();
for (int i = 0; i < 80; i++) {
sb.append(selects[r.nextInt(selects.length)]);
}
System.out.println(sb);
//定义一个map集合记录最终信息
Map<Character,Integer> infos = new HashMap<>();
//遍历学生选择的数据
for (int i = 0; i < sb.length(); i++) {
//提取当前选择的字符
char ch = sb.charAt(i);
//判断map集合中是否存在这个键
if (infos.containsKey(ch)){
//如果存在此景点,让值+1
infos.put(ch,infos.get(ch)+1);
}else {
//说明此经典第一次统计
infos.put(ch,1);
}
}
System.out.println(infos);
System.out.println("=================================");
/**集合的嵌套
* 可以选择多个景点
*/
//1.程序记录每个学生选择的情况,使用map集合存储
Map<String, List<String>> date =new HashMap<>();//集合嵌套
//把学生选择的数据存进去
List<String> list = new ArrayList<>();
Collections.addAll(list,"A","B");
date.put("罗勇",list);
List<String> list1 = new ArrayList<>();
Collections.addAll(list1,"C","B","D");
date.put("刘备",list1);
System.out.println(date);
//统计每个景点选择的人数
Map<String,Integer> map = new HashMap<>();
//提取所有人选择的景点的信息
Collection<List<String>> values = date.values();
System.out.println(values);
for (List<String> value : values) {
for (String s : value) {
if (map.containsKey(s)){
map.put(s,map.get(s)+1);
}else {
map.put(s,1);
}
}
}
System.out.println(map);
}
}
四、Map集合的实现类HashMap
1.HashMap的特点
①HashMap是Map里面的一个实现类。特点都是由键决定的:无序,不重复,无索引。
②没有额外需要学习的特有方法,直接使用Map里面的方法就可以了。
③HashMap跟HashSet底层原理是一模一样的,都是哈希表结构,只是HashMap的每个元素包含两个值而已。
④实际上:Set系列集合的底层就是Map实现的,只是Set集合中的元素只要键数据,不要值数据而已。
2.HashMap的特点和底层原理
①由键决定:无序,不重复,无索引。HashMap底层是哈希表结构的。
②依赖hashMap方法和equals方法保证键的唯一。
③如果键要存储的是自定义的对象,需要重写hashCode和equals方法;
④基于哈希表,增删改查的性能都较好;
五、Map集合的实现类LinkedHashMap
1.概述和特点
由键决定:有序,不重复,无索引。
这里的有序指的是保证存储和取出的元素顺序一致。
2.原理:
底层数据结构依然是哈希表,只是每个键值对元素又额外的多了一个双链表的机制记录存储的顺序。
六、Map集合的实现类TreeMap
1.概述和特点
①由键决定特性:不重复,无索引,可排序。
②可排序:按照键数据的大小默认升序(由小到大)排序,只能对键排序。
③注意:TreeMap集合是一定要排序的,可以默认排序,也可以将键按照指定的规则进行排序。
④TreeMap跟TreeSet的原理是一样的。
2.TreeMap集合自定义排序规则有2种:
类实现Comparable接口,重写比较规则;
集合自定义Comparator比较器对象,重写比较规则;
七·、不可变集合
1.什么是不可变集合?
①不可变集合就是不可被修改的集合;
②集合的数据项在创建的时候提供,并在整个生命周期中都不可改变。否则报错。
2.为什么要创建不可变集合?
①如果某个数据不能被修改,把它防御性的拷贝到不可变集合中是个很好的实践;
②或者当集合对象被不可信的库调用时,不可变形式是安全的;
3.如何创建不可变集合?
在List,Set,Map接口中,都存在of方法,可以创建一个不可变的集合。
4.代码演示:
import java.util.List;
/** 不可变集合 不可被修改的集合
* 集合的数据在创建的时候提供,并且在生命周期中都不可被修改,否则报错。
* 为什么创建不可变集合 :数据不能被修改的时候或者集合对象被不可信的库调用的时候,不可变形式是安全的。
* List、Set、Map、都存在of方法,可以创建一个不可变的集合 :创建一个具有指定元素的集合
*
*/
public class NoCharge_Demo6 {
public static void main(String[] args) {
List<Double> lists = List.of(569.0, 461.7, 356.5, 465.4);//不能new集合,new的集合是可变的
// lists.add(689); //不可添加,不可修改,不可变的固定数据
System.out.println(lists);
double score = lists.get(1);//仅可查看
System.out.println(score);
}
}