一.Map的概述
1.什么是Map集合
Collection称为单列集合,元素的孤立存在的
Map称为双列集合
注意:Collection是单集合的根接口
Map是双列集合的根接口
2.Map集合的特点
a.Collection元素是孤立的,Map的成对的
b.Map集合的键不能重复(唯一的),值是可以重复的,通过键能找到一个值。
二.Map集合中常用子类
1.HashMap集合介绍
底层是哈希表结构
无序的
2.LinkedHashMap集合的介绍
底层是链表+哈希表结构
有序的
3.Map接口中通用的方法
增:public put(K 键,V 值);向Map集合中添加一个键值对。返回被覆盖的键值对的值
删:public remove(K 键);根据键,删除集合中键值对。返回被删除的键值对的值
改:无
查:public get(K 键值);根据键 获取集合中的对应值
其他:
public boolean containsKey(K key);//判断集合中是否包含指定的键
public int size();//返回Map中键值对的个数
代码:
public static void main(String[] args) {
//1.使用Map集合 进行增删改查
//实现类:HashMap(无序) LinkHashMap(有序)
Map<String,Integer> map=new HashMap<String, Integer>();
//2.添加键值对
map.put("小米6p",1988);
map.put("vivo",18784);
map.put("oppo",1525);
map.put("苹果",8542);
//3.删除
map.remove("vivo");
//4.修改
map.put("oppo",2000);
System.out.println(map);
//5.个数
int size = map.size();
System.out.println(size);
//6.判断包不包含这个键
boolean vivo = map.containsKey("vivo");
System.out.println(vivo);
}
4.Map的遍历方式一:以键找值的方式
注意:Map集合 第一没有下标 第二也没有继承Collection所以没有迭代器
代码:
public static void main(String[] args) {
Map<String,Integer> map=new HashMap<String, Integer>();
map.put("小米6p",1988);
map.put("vivo",18784);
map.put("oppo",1525);
map.put("苹果",8542);
//遍历:以键找值
Set<String> keySet= map.keySet();
//使用迭代器
Iterator<String> iterator = keySet.iterator();
//标准遍历
while (iterator.hasNext()){
String key = iterator.next();
Integer value = map.get(key);
System.out.println(key+"="+value);
}
}
5.Map的遍历方式二:键值对(Entry)方式
代码:
public static void main(String[] args) {
Map<String,Integer> map=new HashMap<String, Integer>();
map.put("小米6p",1988);
map.put("vivo",18784);
map.put("oppo",1525);
map.put("苹果",8542);
//遍历:以键找值
Set<String> keySet= map.keySet();
//使用迭代器
Iterator<String> iterator = keySet.iterator();
//标准遍历
while (iterator.hasNext()){
String key = iterator.next();
Integer value = map.get(key);
System.out.println(key+"="+value);
}
}
6.练习1:使用HashMap保存自定义对象
Student类:
public class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public Student() {
}
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;
}
@Override
public String toString() {
return "Student{" +
"name=‘" + name + ‘\‘‘ +
", age=" + age +
‘}‘;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Student)) return false;
Student student = (Student) o;
return age == student.age &&
Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
实现类:
public static void main(String[] args) {
Map<Student,String> map=new HashMap<Student, String>();
//2.添加数据
map.put(new Student("小草",5),"北京");
map.put(new Student("小花",1),"北京");
map.put(new Student("小树",4),"上海");
map.put(new Student("小苗",8),"深圳");
map.put(new Student("小虾",66),"西安");
System.out.println(map);
map.put(new Student("小草",5),"北京");
System.out.println(map);
}
7.练习2:使用LinkedHashMap保存自定义对象
实现类:
/练习,每位学生(姓名,年龄)都有自己的家庭住址,学生作为键,家庭住址为值
//1.定义Map集合
Map<Student,String> map=new LinkedHashMap<Student, String>();
//2.添加数据
map.put(new Student("小草",5),"北京");
map.put(new Student("小花",5),"北京");
map.put(new Student("小树",5),"上海");
map.put(new Student("小苗",5),"深圳");
map.put(new Student("小虾",5),"西安");
//1.第一种遍历方法
Set<Student> students = map.keySet();
Iterator<Student> iterator = students.iterator();
while (iterator.hasNext()){
Student next = iterator.next();
String s = map.get(next);
System.out.println(s+","+next);
}
System.out.println("==================");
//2.第二种遍历方法
Set<Map.Entry<Student, String>> entries = map.entrySet();
for (Map.Entry<Student, String> entry : entries) {
Student key = entry.getKey();
String value = entry.getValue();
System.out.println(key+"="+value);
}
}
注意:
使用hashSet或者LinkedMap保证自定义的键时,由于我们保证键的唯一性
必须重写自定义类中的HahCode和equals
8.Map集合综合练习
需求:
计算一个字符串中每种字符出现次数
思考:
以上这种题目,必须使用Map<Character ,Integer>
步骤
a.定义Map集合,保存字符和对应的次数
b.遍历字符串,取出每一个字符
c.如果该字符在Map中已经出现了,那么需要把出现次数增加一
如果该字符在Map中没有出现,那么需要添加集合中添加该字符,并且为1
d.打印Map集合
代码:
public static void main(String[] args) {
//控制台输入字符串
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个字符串");
String next = scanner.next();
//定义Map集合,保存字符和对应的次数
HashMap<Character, Integer> hashMap = new HashMap<Character, Integer>();
//遍历字符串,取出每一个字符
for (int i = 0; i < next.length(); i++) {
char c = next.charAt(i);
if (hashMap.containsKey(c)){
hashMap.put(c,hashMap.get(c)+1);
}else {
hashMap.put(c,1);
}
}
System.out.println(hashMap);
}
三.补充知识点
1.JDK快速创建集合的方法
List<Integer> nums=List.of(10,20,30,40,50);
Set<String> set=Set.of("a","b","c","d");
Map<String,Integer> map=Map.of("张三",18,"李四",19,"王五",20);
2.快速创建集合的注意事项
使用以上三种方式创建的集合,得到的集合都是不可变的集合
对不可变集合进行添加,删除,修改,都会抛出UnsupportedOperationException
3.Debug模式追踪
F8:代码向下执行一行
F7:进入某个方法
Ctrl+F2:立即停止程序
F9:运行到下一个断点处,如果没有下一个断点,运行完毕整个程序
四.模拟斗地主案例
核心:为每一张牌,设置一个编号,要求牌越大 编号越大
步骤分析:
1.需要准备编号和牌对应的Map<Integer,String>集合
2.准备一副牌(54个编号)
3.洗牌(编号集合)
4.发牌(编号)
5.排序(编号)
6.转牌(把编号转成对应的牌)
7.看牌
代码实现:
public static void main(String[] args) {
// 1.需要准备编号和牌对应的Map<Integer,String>集合
ArrayList<Integer> cardsBox = new ArrayList<Integer>();
LinkedHashMap<Integer, String> map = new LinkedHashMap<Integer, String>();
String[] colars = {"?", "?", "?", "?"};
String[] Licensing = {"3", "4", "5", "6", "7", "8", "9", "10", "j", "Q", "K", "A", "2"};
//产生编号和牌
int id = 1;
//注意:这里必须外层先遍历 数字,内遍历花色
for (String s : Licensing) {
for (String colar : colars) {
//连接牌
String s1 = colar + s;
//保存到map中
map.put(id, s1);
//同时添加牌
cardsBox.add(id);
id++;
}
}
map.put(id, "小s");
cardsBox.add(id);
id++;
map.put(id, "大s");
cardsBox.add(id);
//准备一副牌(54个编号)
System.out.println(cardsBox);
// 3.洗牌(编号集合)
Collections.shuffle(cardsBox);
// 3.发牌(剩余3张,作为底牌)
ArrayList<Integer> p1 = new ArrayList<Integer>();
ArrayList<Integer> p2 = new ArrayList<Integer>();
ArrayList<Integer> p3 = new ArrayList<Integer>();
ArrayList<Integer> ps = new ArrayList<Integer>();
// 4.发牌(编号)
for (int i = 0; i< cardsBox.size(); i++) {
//先取出牌
Integer s = cardsBox.get(i);
if (i >= 51) {
ps.add(s);
} else {
if (i % 3 == 0) {
p1.add(s);
} else if (i % 3 == 1) {
p2.add(s);
} else {
p3.add(s);
}
}
}
System.out.println(cardsBox);
// 5.排序(编号)
System.out.println(cardsBox);
Collections.sort(p1);
Collections.sort(p2);
Collections.sort(p3);
Collections.sort(ps);
// 6.转牌(把编号转成对应的牌)
lookCards(p1, map);
lookCards(p2, map);
lookCards(p3, map);
lookCards(ps, map);
}
//转牌,看牌
private static void lookCards(ArrayList<Integer> p1, Map<Integer, String> map) {
//1.遍历集合取出所有的编号
for (Integer carId : p1) {
String s = map.get(carId);
System.out.print(s+" ");
}
System.out.println();
}
/**
* 目前是按照升序排序的
* 修改成降序
* 方法1:倒叙遍历玩家的编号
* 方法2:定义map集合时牌越大编号越小
* 方法3:Collection.sort(集合,自定义比较器)
*/
}
注意:
sort(List<T> list);//根据元素的自然顺序对指定列表按升序进行排序
原文:https://www.cnblogs.com/linlin1211/p/10271098.html