一. Map集合
1.Map集合存在的意义
在生活中,有时候存在像如下这样的数据
每个学生都有一个学号,一个学号只能由一个姓名对应,并且学号是不可能重复。
在Java中为了方便的存储和使用这类的数据,所以便有了Map集合。
2.Map集合的特点
(1)Map是双列集合,存储的是键值对,键唯一。
(2)每个键最多只能映射到一个值。
(3)Map集合的数据结构针对键有效,跟值无关。
3.Map集合的功能概述
添加功能
V put(K key,V value):添加元素。这个其实还有另一个功能?替换
如果键是第一次存储,就直接存储元素,返回null
如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值
删除功能
void clear():移除所有的键值对元素
V remove(Object key):根据键删除键值对元素,并把值返回
判断功能
boolean containsKey(Object key):判断集合是否包含指定的键
boolean containsValue(Object value):判断集合是否包含指定的值
boolean isEmpty():判断集合是否为空
获取功能
Set<Map.Entry<K,V>> entrySet(): 返回一个键值对的Set集合
V get(Object key):根据键获取值
Set<K> keySet():获取集合中所有键的集合
Collection<V> values():获取集合中所有值的集合
长度功能
int size():返回集合中的键值对的对数
4.案例演示
(1)基本功能测试
package com.westmo1.demo6;
import java.util.HashMap;
public class MyDemo1 {
public static void main(String[] args) {
HashMap<Integer, String> hashMap = new HashMap<>();
String s = hashMap.put(001, "张三");
System.out.println(s);//null 如果是第一次存储,直接存储元素,返回null
String s1 = hashMap.put(001, "李四");
System.out.println(s1);//键不是第一次存在的,就会把以前的值替换,返回以前的值
hashMap.put(002,"王五");
hashMap.put(003,"呼呼呼呼");
//hashMap.clear();//移除所有键值对元素
String remove = hashMap.remove(001);//根据键删除键值对元素,并把值返回
System.out.println(remove);
boolean b = hashMap.containsKey(002);//判断集合是否包含指定的键
boolean b1 = hashMap.containsValue(001);//判断集合是否包含指定的值
int size = hashMap.size();//获取集合中键值对的对数
boolean empty = hashMap.isEmpty();//判断集合是否为空
}
}
(2)Map集合遍历演示
package com.westmo1.demo6;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MyDemo2 {
public static void main(String[] args) {
HashMap<Integer, String> hashMap = new HashMap<>();
hashMap.put(1,"张三");
hashMap.put(2,"张三三");
hashMap.put(10,"张莎莎");
hashMap.put(121,"刘沙和尚");
//遍历方式1
Set<Integer> integers = hashMap.keySet();
for (Integer integer : integers) {
String s = hashMap.get(integer);
System.out.println(integer+"---"+s);
}
//遍历方式2
Set<Map.Entry<Integer, String>> entries = hashMap.entrySet();
for (Map.Entry<Integer, String> entry : entries) {
Integer key = entry.getKey();
String value = entry.getValue();
System.out.println(key+"==="+value);
}
}
}
三.HashMap
键的数据结构是哈希表
1.HashMap存储的键值对中的值是自定义对象
package com.westmo1.demo6;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MyDemo3 {
public static void main(String[] args) {
HashMap<String, Student> hashMap = new HashMap<>();
hashMap.put("0001",new Student("张三",14));
hashMap.put("0002",new Student("李四",19));
hashMap.put("0003",new Student("王五",23));
Set<String> strings = hashMap.keySet();
for (String string : strings) {
Student student = hashMap.get(string);
System.out.println(string+"--"+student.getName()+","+student.getAge());
}
Set<Map.Entry<String, Student>> entries = hashMap.entrySet();
for (Map.Entry<String, Student> entry : entries) {
String key = entry.getKey();
Student value = entry.getValue();
System.out.println(key+"--"+value.getName()+","+value.getAge());
}
}
}
package com.westmo1.demo6;
public class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
2.HashMap存储的键值对中的键是自定义对象
package com.westmo1.demo6;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MyDemo3 {
public static void main(String[] args) {
HashMap<Student, String> hashMap = new HashMap<>();
hashMap.put(new Student("张三", 14), "0001");
hashMap.put(new Student("李四", 19), "0002");
hashMap.put(new Student("王五", 23), "0003");
hashMap.put(new Student("李四",19),"0002");
//方式一遍历
Set<Student> strings = hashMap.keySet();
for (Student string : strings) {
String s = hashMap.get(string);
System.out.println(string.getName()+","+string.getAge()+"---"+s);
}
//方式二遍历
Set<Map.Entry<Student, String>> entries = hashMap.entrySet();
for (Map.Entry<Student, String> entry : entries) {
Student key = entry.getKey();
String value = entry.getValue();
System.out.println(key.getName()+","+key.getAge()+"---"+value);
}
}
}
程序运行的结果是
李四,19---0002
李四,19---0002
张三,14---0001
王五,23---0003
李四,19---0002
李四,19---0002
张三,14---0001
王五,23---0003
可以发现,集合中存储李四,19—002元素的时候出现1了重复。这是不符合HashMap集合的规范的,因为自定义的Student类,没有重写hashCode和equals方法。
//重写时候的结果
王五,23---0003
张三,14---0001
李四,19---0002
王五,23---0003
张三,14---0001
李四,19---0002
四.LinkedHashMap
1.数据结构
键的数据结构是链表和哈希表,键的特点:有序且唯一,链表保证有序,哈希表保证唯一。
2.
package com.westmo1.demo5;
import java.util.LinkedHashMap;
import java.util.Set;
public class MyDemo6 {
public static void main(String[] args) {
LinkedHashMap<String, String> linkedHashMap = new LinkedHashMap<>();
linkedHashMap.put("001","张三");
linkedHashMap.put("003","张三达到");
linkedHashMap.put("002","张三答");
Set<String> strings = linkedHashMap.keySet();
for (String string : strings) {
String s = linkedHashMap.get(string);
System.out.println(string+"---"+s);
}
}
}
五.TreeMap
1.底层数据结构是二叉树,能够对元素进行排序
2.排序
(1)自然排序
- 概念:使用空参构造,对元素有要求,要求元素必须实现Comparable接口,重写compare方法,根据此方法返回值的正负0来决定元素的排列顺序。
- 案例演示
package com.westmo1.demo5;
import java.util.Set;
import java.util.TreeMap;
public class MyDemo7 {
public static void main(String[] args) {
TreeMap<Student1, String> treeMap = new TreeMap<>();
treeMap.put(new Student1("张三",13),"s001");
treeMap.put(new Student1("李四的小达达",13),"s002");
treeMap.put(new Student1("啦啦",33),"s003");
treeMap.put(new Student1("呼呼呼呼呼",78),"s006");
treeMap.put(new Student1("嘿嘿嘿嘿",25),"s009");
Set<Student1> student1s = treeMap.keySet();
for (Student1 student1 : student1s) {
String value = treeMap.get(student1);
System.out.println(student1.getName()+","+student1.getAge()+"---"+value);
}
}
}
//根据姓名长度来排序
class Student1 implements Comparable<Student1>{
private String name;
private int age;
public Student1(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
@Override
public int compareTo(Student1 o) {
int num=this.name.length()-o.name.length();
int num1=num==0?this.name.compareTo(o.name):num;
int num2=num1==0?this.age-o.age:num1;
return num2;
}
}
(2)比较器排序
- 概念:使用有参构造,需要传入一个比较器Comparetor,重新compare方法。
- 案例演示
package com.westmo1.demo5;
import java.util.Comparator;
import java.util.Set;
import java.util.TreeMap;
public class MyDemo7 {
public static void main(String[] args) {
TreeMap<Student1, String> treeMap = new TreeMap<>(new Comparator<Student1>() {
@Override
public int compare(Student1 o1, Student1 o2) {
int num=o1.getName().length()-o2.getName().length();
int num1=num==0?o1.getName().compareTo(o2.getName()):num;
int num2=num1==0?o1.getAge()-o2.getAge() :num1;
return num2;
}
});
treeMap.put(new Student1("张三",13),"s001");
treeMap.put(new Student1("李四的小达达",13),"s002");
treeMap.put(new Student1("啦啦",33),"s003");
treeMap.put(new Student1("呼呼呼呼呼",78),"s006");
treeMap.put(new Student1("嘿嘿嘿嘿",25),"s009");
Set<Student1> student1s = treeMap.keySet();
for (Student1 student1 : student1s) {
String value = treeMap.get(student1);
System.out.println(student1.getName()+","+student1.getAge()+"---"+value);
}
}
}
class Student1{
private String name;
private int age;
public Student1(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
六.Map集合练习
1.统计字符串中每个字符出现的次数
“aababcabcdabcde”,获取字符串中每一个字母出现的次数要求结果:a(5)b(4)c(3)d(2)e(1)
package com.westmo1.demo5;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
public class MyDemo8 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("输入字符串");
String s = scanner.nextLine();
HashMap<Character, Integer> hashMap = new HashMap<>();//用HashMap存储,键代表字符,值代表个数
for (int i = 0; i < s.length(); i++) {
char c1 = s.charAt(i);
if (hashMap.containsKey(c1)) {//判断集合中是否有这个键
Integer integer = hashMap.get(c1);//有这个键时对应的值加1
hashMap.put(c1,integer+1);
}else{
hashMap.put(c1,1);
}
}
Set<Map.Entry<Character, Integer>> entries = hashMap.entrySet();
for (Map.Entry<Character, Integer> entry : entries) {
Character key = entry.getKey();
Integer value = entry.getValue();
System.out.println(key+"("+value+")");
}
}
}
2.集合嵌套
- (1)存储如下数据
基础班
张三 20
李四 22
就业班
王五 21
赵六 23
package com.westmo1.demo5;
import java.util.HashMap;
import java.util.Set;
public class MyDemo9 {
public static void main(String[] args) {
HashMap<String, Integer> hashMap = new HashMap<>();
hashMap.put("张三",20);
hashMap.put("李四",22);
HashMap<String, Integer> hashMap1 = new HashMap<>();
hashMap1.put("王五",21);
hashMap1.put("赵六",23);
HashMap<String, HashMap<String, Integer>> hashMap2 = new HashMap<>();
hashMap2.put("基础班",hashMap);
hashMap2.put("就业班",hashMap1);
Set<String> strings = hashMap2.keySet();
for (String string : strings) {
System.out.println(string);
HashMap<String, Integer> hashMap3 = hashMap2.get(string);
Set<String> strings1 = hashMap3.keySet();
for (String s : strings1) {
Integer integer = hashMap3.get(s);
System.out.println("\t"+s+"--"+integer);
}
System.out.println();
}
}
}
- (2)存储如下数据
三国演义
吕布
周瑜
笑傲江湖
令狐冲
林平之
神雕侠侣
郭靖
杨过
package com.westmo1.demo5;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MyDemo10 {
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<String>();
arrayList.add("吕布");
arrayList.add("周瑜");
ArrayList<String> arrayList1 = new ArrayList<>();
arrayList1.add("令狐冲");
arrayList1.add("林平之");
ArrayList<String> arrayList2 = new ArrayList<>();
arrayList2.add("郭靖");
arrayList2.add("杨过");
HashMap<String, ArrayList<String>> hashMap = new HashMap<>();
hashMap.put("三国演义",arrayList);
hashMap.put("笑傲江湖",arrayList1);
hashMap.put("神雕侠侣",arrayList2);
Set<Map.Entry<String, ArrayList<String>>> entries = hashMap.entrySet();
for (Map.Entry<String, ArrayList<String>> entry : entries) {
String key = entry.getKey();
System.out.println(key);
for (String s : entry.getValue()) {
System.out.println("\t"+s);
}
}
}
}
3.集合综合练习
模拟斗地主的洗牌和发牌,并且要让玩家拿到的排是按顺序排好的。
- 大致思路:我们可以使用HashMap集合来存储牌,给每个牌编上号,作为集合的键。洗牌的时候洗的就是键,然后用TreeSet集合存储每个人的牌(按照编号分),最后根据编号(TreeSet已经排好序)输出对应的值,就是每个人的牌。
- 代码
package com.westmo1.demo5;
import java.util.*;
public class MyDemo11 {
public static void main(String[] args) {
HashMap<Integer, String> hashMap = new HashMap<>();
int index=0;
String[] colors={"♠","♣","♥","♦"};
String[] num={"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
for (int i = 0; i < num.length; i++) {
for (int i1 = 0; i1 < colors.length; i1++) {
hashMap.put(index,num[i]+colors[i1]);
index++;
}
}
hashMap.put(index,"小王");
hashMap.put(index+1,"大王");
ArrayList<Integer> arrayList = new ArrayList<Integer>();
Set<Integer> integers = hashMap.keySet();
for (Integer integer : integers) {
arrayList.add(integer);
}
Collections.shuffle(arrayList);//洗牌,打乱顺序
TreeSet<Integer> play1 = new TreeSet<Integer>();
TreeSet<Integer> play2 = new TreeSet<Integer>();
TreeSet<Integer> play3 = new TreeSet<Integer>();
TreeSet<Integer> dipai = new TreeSet<Integer>();
for (int i = 0; i < arrayList.size(); i++) {//发牌
if(i>=51){
dipai.add(arrayList.get(i));
}else if (i%3==0) {
play1.add(arrayList.get(i));
}else if (i%3==1) {
play2.add(arrayList.get(i));
}else if (i%3==2){
play3.add(arrayList.get(i));
}
}
LookPoker("一号玩家",play1,hashMap);
LookPoker("二号玩家",play2,hashMap);
LookPoker("三号玩家",play3,hashMap);
LookPoker("底牌",dipai,hashMap);
}
private static void LookPoker(String play, TreeSet<Integer> play1, HashMap<Integer, String> hashMap) {
System.out.print(play+":");
for (Integer integer : play1) {
String s = hashMap.get(integer);
System.out.print(s+" ");
}
System.out.println();
}
}