目录
认识 Map 集合
Map的常用方法
Map的遍历
遍历方式一:键找值
遍历方式二:键值对
遍历方式三:Lambda
案例:统计投票人数
HashMap
LinkedHashMap
TreeMap
. Map 集合称为双列集合,格式:(key1=value1,key2=value2,key3=value3,..),一次需要存一对数据做为一个元素.
. Map 集合的每个元素" key = value "称为一个键值对/键值对对象/一个 Entry 对象, Map 集合也被叫做"键值对集合"
· Map 集合的所有键是不允许重复的,但值可以重复,键和值是一一对应的,每一个键只能找到自己对应的值
Map 集合体系的特点
注意: Map 系列集合的特点都是由键决定的,值只是一个附属品,值是不做要求的
HashMap (由键决定特点):无序、不重复、无索引;(用的最多)
● LinkedHashMap (由键决定特点):由键决定的特点:有序、不重复、无索引。
● TreeMap (由键决定特点):按照大小默认升序排序、不重复、无索引。
为什么要先学习 Map 的常用方法?
● Map 是双列集合的祖宗,它的功能是全部双列集合都可以继承过来使用的。
Map 的常用方法如下:
package com.xinbao.d4_map;
import java.util.*;
public class MapTest1 {
public static void main(String[] args) {
//Map map = new HashMap<>();//无序,不重复,无索引
// {玛瑙=1000, null=null, 钻石=10000, 宝石=10000, 水晶=300}
Map map = new LinkedHashMap<>();//有序,不重复,无索引
// {水晶=300, 玛瑙=1000, 宝石=10000, 钻石=10000, null=null}
map.put("水晶", 100);
map.put("玛瑙", 1000);
map.put("宝石", 10000);
map.put("水晶", 300);
map.put("钻石", 10000);
map.put(null, null);
System.out.println(map);
Map treemap = new TreeMap<>();//可排序,不重复,无索引
// {115=---, 123=ufhf, 234=,,,, 345====, 1156=+++\}
treemap.put(123, "ufhf");
treemap.put(234, ",,,");
treemap.put(345, "===");
treemap.put(115, "---");
treemap.put(1156, "+++");
treemap.put(1156, "+++\\");
System.out.println(treemap);
// public int size ():获取集合大小
System.out.println(map.size());//5
// public void clear ()//清空集合
// map.clear();
// System.out.println(map);//{}
// public boolean isEmpty ()//判空
System.out.println(map.isEmpty());//true
System.out.println(treemap.isEmpty());//false
// public V get ( Object key )//根据键获取对应值
String value = treemap.get(123);
System.out.println(value);//ufhf
// public V remove ( Object key )//根据键删除整个元素
System.out.println(map.remove("玛瑙"));//1000
map.remove(null);
System.out.println(map);//{水晶=300, 宝石=10000, 钻石=10000}
// public boolean containskey ( Object key )//判断是否包含某个键
System.out.println(map.containsKey("水晶"));//true
// public boolean containsValue ( Object value )
System.out.println(map.containsValue(10000));//true
// public Set < K > keySet ()//获取Map集合的全部键
Set keys = map.keySet();
System.out.println(keys);//[水晶, 宝石, 钻石]
// public Collection < V > values ()//获取全部值
Collection values = map.values();
System.out.println(values);//[300, 10000, 10000]
//把其他集合倒入Map
Map map2 = new HashMap<>();
map2.put("水晶",560);
map2.put("黄金",50000);
map2.put("祖母绿",9900);
System.out.println(map2);
map.putAll(map2);//{祖母绿=9900, 黄金=50000, 水晶=560}
System.out.println(map);//{水晶=560, 宝石=10000, 钻石=10000, 祖母绿=9900, 黄金=50000}
}
}
package com.xinbao.d5_map_traverse;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MapTest1 {
public static void main(String[] args) {
Map map = new HashMap<>();
map.put("蜘蛛精" , 162.5);
map.put("蜘蛛精" , 185.5);
map.put("牛魔王" , 172.5);
map.put("至尊宝" , 182.5);
map.put("紫霞仙子" , 167.5);
map.put("玉兔精" , 163.5);
System.out.println(map);
//1、获取map的全部键
Set keys = map.keySet();
System.out.println(keys);
//2、遍历全部键,根据键获取对应值
for (String key : keys) {
double value = map.get(key);
System.out.println(key + "--->" + value);
}
}
}
E:\JVsoft\Java\jdk-17\bin\java.exe -javaagent:E:\JVsoft\IntelliJIDEA2021.1.1\lib\idea_rt.jar=35289:E:\JVsoft\IntelliJIDEA2021.1.1\bin -Dfile.encoding=UTF-8 -classpath E:\JVsoft\code\out\production\collection-map-stream-app com.xinbao.d5_map_traverse.MapTest1
{蜘蛛精=185.5, 牛魔王=172.5, 至尊宝=182.5, 紫霞仙子=167.5, 玉兔精=163.5}
[蜘蛛精, 牛魔王, 至尊宝, 紫霞仙子, 玉兔精]
蜘蛛精--->185.5
牛魔王--->172.5
至尊宝--->182.5
紫霞仙子--->167.5
玉兔精--->163.5
Process finished with exit code 0
package com.xinbao.d5_map_traverse;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MapTest2 {
public static void main(String[] args) {
Map map = new HashMap<>();
map.put("蜘蛛精" , 162.5);
map.put("蜘蛛精" , 185.5);
map.put("牛魔王" , 172.5);
map.put("至尊宝" , 182.5);
map.put("紫霞仙子" , 167.5);
map.put("玉兔精" , 163.5);
System.out.println(map);
//调用Map集合提供的entrySet方法,把Map集合转换成键值对类型的Set集合
Set> entries = map.entrySet();
for (Map.Entry entry : entries) {
String key = entry.getKey();
Double value = entry.getValue();
System.out.println(key + "--->" + value);
}
}
}
E:\JVsoft\Java\jdk-17\bin\java.exe -javaagent:E:\JVsoft\IntelliJIDEA2021.1.1\lib\idea_rt.jar=62032:E:\JVsoft\IntelliJIDEA2021.1.1\bin -Dfile.encoding=UTF-8 -classpath E:\JVsoft\code\out\production\collection-map-stream-app com.xinbao.d5_map_traverse.MapTest2
{蜘蛛精=185.5, 牛魔王=172.5, 至尊宝=182.5, 紫霞仙子=167.5, 玉兔精=163.5}
蜘蛛精--->185.5
牛魔王--->172.5
至尊宝--->182.5
紫霞仙子--->167.5
玉兔精--->163.5
Process finished with exit code 0
package com.xinbao.d5_map_traverse;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;
public class MapTest3 {
public static void main(String[] args) {
Map map = new HashMap<>();
map.put("蜘蛛精" , 162.5);
map.put("蜘蛛精" , 185.5);
map.put("牛魔王" , 172.5);
map.put("至尊宝" , 182.5);
map.put("紫霞仙子" , 167.5);
map.put("玉兔精" , 163.5);
System.out.println(map);
map.forEach((k,v)->{
System.out.println(k + "-->" + v);
});
// map.forEach(new BiConsumer() {
// @Override
// public void accept(String k, Double v) {
// System.out.println(k + "-->" + v);
// }
// });
}
}
E:\JVsoft\Java\jdk-17\bin\java.exe -javaagent:E:\JVsoft\IntelliJIDEA2021.1.1\lib\idea_rt.jar=61871:E:\JVsoft\IntelliJIDEA2021.1.1\bin -Dfile.encoding=UTF-8 -classpath E:\JVsoft\code\out\production\collection-map-stream-app com.xinbao.d5_map_traverse.MapTest3
{蜘蛛精=185.5, 牛魔王=172.5, 至尊宝=182.5, 紫霞仙子=167.5, 玉兔精=163.5}
蜘蛛精-->185.5
牛魔王-->172.5
至尊宝-->182.5
紫霞仙子-->167.5
玉兔精-->163.5
Process finished with exit code 0
需求
.某个班级80名学生,现在需要组织秋游活动,班长提供了四个景点依次是( A 、 B 、 C 、 D ),每个学生只能选择一个景点,请统计出最终哪个景点想去的人数最多。
分析
.将80个学生选择的数据拿到程序中去,[ A , A , B , A , B , C , D ,.]
.准备一个 Map 集合用于存储统计的结果, Map < String , Integer >,键是景点,值代表投票量。
遍历80个学生选择的景点,每遍历一个景点,就看 Map 集合中是否存在该景点,不存在存入"景点=1",存在则其对应值+1,
package com.xinbao.d5_map_traverse;
import java.util.*;
public class MapDemo4 {
public static void main(String[] args) {
//1.把80个学生选择的景点数据拿到程序中来
List data = new ArrayList<>();
String[] selects = {"A", "B", "C", "D"};
Random r = new Random();
for (int i = 0; i < 80; i++) {
//每次模拟一个学生选择一个景点,存入到集合中去
int index = r.nextInt(4);//0,1,2,3
data.add(selects[index]);
}
System.out.println(data);
//2.准备一个Map集合用于统计最终结果
Map result = new HashMap<>();
//3.开始遍历80个景点数据
for (String s : data) {
//问问Map集合中是否存在该景点
if (result.containsKey(s)){
//已经统计过,人数+1
result.put(s,result.get(s)+1);
}else {
//未统计,初值为1
result.put(s,1);
}
}
System.out.println(result);
E:\JVsoft\Java\jdk-17\bin\java.exe -javaagent:E:\JVsoft\IntelliJIDEA2021.1.1\lib\idea_rt.jar=22896:E:\JVsoft\IntelliJIDEA2021.1.1\bin -Dfile.encoding=UTF-8 -classpath E:\JVsoft\code\out\production\collection-map-stream-app com.xinbao.d5_map_traverse.MapDemo4
[D, D, A, B, A, B, C, B, D, A, A, D, C, A, B, A, D, A, A, A, C, D, C, C, D, D, B, D, A, A, B, D, D, C, B, B, B, C, C, A, C, A, C, C, B, A, D, D, D, B, C, C, D, C, D, A, C, C, B, D, C, A, B, D, C, B, B, D, B, C, A, C, D, A, A, A, A, D, A, B]
{A=22, B=17, C=20, D=21}
HashMap 底层是基于哈希表实现的
● HashMap 集合是一种增删改查数据,性能都较好的集合
但是它是无序,不能重复,没有索引支持的(由键决定特点)· HashMap 的键依赖 hashCode 方法和 equals 方法保证键的唯一
●如果键存储的是自定义类型的对象,可以通过重写 hashCode 和 equals 方法,这样可以保证多个对象内容一样时, HashMap 集合就能认为是重复的。
package com.xinbao.d6_map_impl;
import java.util.Objects;
public class Student {
private String name;
private int age;
private double height;
public Student() {
}
@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 && Double.compare(student.height, height) == 0 && Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age, height);
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", height=" + height +
'}';
}
public Student(String name, int age, double height) {
this.name = name;
this.age = age;
this.height = height;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
}
package com.xinbao.d6_map_impl;
import java.util.HashMap;
import java.util.Map;
public class Test1HashMap {
public static void main(String[] args) {
Map map = new HashMap<>();
map.put(new Student("蜘蛛精", 25, 168.5), "盘丝洞");
map.put(new Student("蜘蛛精", 25, 168.5), "水帘洞");
map.put(new Student("至尊宝", 23, 163.5), "水帘洞");
map.put(new Student("牛魔王", 28, 183.5), "牛头山");
System.out.println(map);
}
}
E:\JVsoft\Java\jdk-17\bin\java.exe -javaagent:E:\JVsoft\IntelliJIDEA2021.1.1\lib\idea_rt.jar=23469:E:\JVsoft\IntelliJIDEA2021.1.1\bin -Dfile.encoding=UTF-8 -classpath E:\JVsoft\code\out\production\collection-map-stream-app com.xinbao.d6_map_impl.Test1HashMap
{Student{name='至尊宝', age=23, height=163.5}=水帘洞, Student{name='牛魔王', age=28, height=183.5}=牛头山, Student{name='蜘蛛精', age=25, height=168.5}=水帘洞}
特点:不重复、无索引、可排序(按照键的大小默认升序排序,只能对键排序)
.原理: TreeMap 跟 TreeSet 集合的底层原理是一样的,都是基于红黑树实现的排序。
TreeMap 集合同样也支持两种方式来指定排序规则
.让类实现 Comparable 接口,重写比较规则。
● TreeMap 集合有一个有参数构造器,支持创建 Comparator 比较器对象,以便用来指定比较则。
package com.xinbao.d6_map_impl;
import java.util.Objects;
public class Student implements Comparable{
private String name;
private int age;
private double height;
//this o
@Override
public int compareTo(Student o) {
return this.age - o.age;//年龄升序
}
public Student() {
}
@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 && Double.compare(student.height, height) == 0 && Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age, height);
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", height=" + height +
'}';
}
public Student(String name, int age, double height) {
this.name = name;
this.age = age;
this.height = height;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
}
package com.xinbao.d6_map_impl;
import java.util.Comparator;
import java.util.Map;
import java.util.TreeMap;
//有序 不重复 无索引 数组+链表+红黑树
public class Test3TreeMap {
public static void main(String[] args) {
// Map map = new TreeMap<>(new Comparator() {
// @Override
// public int compare(Student o1, Student o2) {
// return Double.compare(o2.getHeight(), o1.getHeight());
// }
// });
Map map = new TreeMap<>((o1, o2) -> Double.compare(o2.getHeight(), o1.getHeight()));
map.put(new Student("蜘蛛精", 25, 168.5), "盘丝洞");
map.put(new Student("蜘蛛精", 25, 168.5), "水帘洞");
map.put(new Student("至尊宝", 23, 163.5), "水帘洞");
map.put(new Student("牛魔王", 28, 183.5), "牛头山");
System.out.println(map);
}
}
E:\JVsoft\Java\jdk-17\bin\java.exe -javaagent:E:\JVsoft\IntelliJIDEA2021.1.1\lib\idea_rt.jar=7230:E:\JVsoft\IntelliJIDEA2021.1.1\bin -Dfile.encoding=UTF-8 -classpath E:\JVsoft\code\out\production\collection-map-stream-app com.xinbao.d6_map_impl.Test3TreeMap
{Student{name='至尊宝', age=23, height=163.5}=水帘洞, Student{name='蜘蛛精', age=25, height=168.5}=水帘洞, Student{name='牛魔王', age=28, height=183.5}=牛头山}
说说:和上次发博有大概一个月了,快一个月没有学习了,一直在焦虑,在内耗,怎么说呢,感觉现在的毕业生压力真的太大了,也怪我前两年没有学门技术,也不是不想好好学,像是被信息差困住了,到快要毕业才体会到,执着于考研,又怕不上了没有技术傍身工作也找不到,真的很后悔,没有早早学门技术,这样才有考研的底气,能给自己留条后路,也没有好好学考研的课,没把基础打好,觉得自己真的很傻,为什么等经历了才知道这些。感觉人生真的很不容易,有的人生在罗马,普通人跌跌撞撞头破血流,什么都要自己摸索自己经历,不知道正确的路怎么走,要走很多弯路,后来知道正确的路了时间也过去了,回不了头了,挺难过不甘的是,自认也不是不努力懒散的人,但是真的像无头苍蝇,干着急白努力,就挺无奈的,也是自己还不够尽心,不想被信息差困住就应该多打听多了解,自己偷过的懒总会加倍偿还吧。
这段时间一直在纠结方向问题,我也是一个爱纠结的人,感觉人生多时是选择大于努力的,走Java是因为Java岗多,但是真的好卷好多人学Java啊,感觉以后这个赛道只会越来越卷,35岁卷不动了又该何去何从,学的人越来越多会不会让这行越来越廉价。其实还挺想走c和c++的,起码还没有被机构入侵,,,而且感觉语法结构上比较贴近考研,相辅相成?但是没有成体系的课,方向也太细分,岗也少,但是以后可能更有竞争力一点也没那么卷吧。很后悔当初没有好好学数电,从数电开始水,基础没打好,后面的硬件一路水过来,要不我就直接嵌入式了,后悔啊,真的有子弹正中眉心的感觉,嵌入式可能前景挺好的吧。个人觉得对前端挺有兴趣的,但是真的不想再新学一个语法了。反正这些有的没的我纠结了整整一个月,每天啥都没干但是焦虑爆炸,昨天把牛客和智联招聘卸载了,不敢再看一眼了,要不又开始纠结又开始内耗。既然抉择不了就随便选一个吧哈哈哈(苦笑),真的觉得很无力很渺小,想变好又处处受限,像个被罩在透明迷宫里的虫子,想去外面,却不知道正确的路,可能有的路走了都找不到回去的路,没有路标指引,只能累死累活走一步看一步,可能走错的代价相当大,站在路口能把自己纠结死,因为走错了的话那可是自己的人生啊。如果是个不透明的迷宫,那眼前也就只有自己的世界,偏偏是个透明的迷宫,能看到外面世界的美好繁华,但是自己就是不知道出口,感觉这个情景还挺贴切的哈哈。
希望我最终能成为那个找到出口的鼠鼠。