文章目录
Map集合
Map集合体系
HashMap
1,Map集合的特点
Map接口概述
查看API可以知道:
将键映射到值的对象
一个映射不能包含重复的键
每个键最多只能映射到一个值
Map接口和Collection接口的不同
Map是双列的,Collection是单列的
Map的键唯一,Collection的子体系Set是唯一的
Map集合的数据结构针对键有效,跟值无关;Collection集合的数据结构是针对元素有效
2, Map集合的功能
a:添加功能
V put(K key,V value):添加元素。这个其实还有另一个功能?替换
如果键是第一次存储,就直接存储元素,返回null
如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值
b:删除功能
void clear():移除所有的键值对元素
V remove(Object key):根据键删除键值对元素,并把值返回
c:判断功能
boolean containsKey(Object key):判断集合是否包含指定的键
boolean containsValue(Object value):判断集合是否包含指定的值
boolean isEmpty():判断集合是否为空
d:获取功能
Set<Map.Entry<K,V>> entrySet(): 返回一个键值对的Set集合
V get(Object key):根据键获取值
Set<K> keySet():获取集合中所有键的集合
Collection<V> values():获取集合中所有值的集合
e:长度功能
int size():返回集合中的键值对的对数
基本功能测试:
public class Test {
public static void main(String[] args) {
HashMap<String, Student> h = new HashMap<>();
//添加功能 V put(K key,V value)
h.put("s001",new Student("张三",23));
h.put("s001", new Student("张三", 29));
h.put("s002", new Student("李四", 24));
h.put("s003", new Student("王五", 25));
//删除功能
//V remove(Object key):根据键删除键值对元素,并把值返回
Student s=h.remove("s001");
System.out.println(s);
//void clear():移除所有的键值对元素
//default boolean remove(Object key,Object value) 删除键值对
boolean b=h.remove("s003",new Student("王五", 25));
System.out.println(b);
//判断功能
//boolean containsKey(Object key):判断集合是否包含指定的键
boolean flag=h.containsKey("s002");
System.out.println(flag);//true
//boolean containsValue(Object value):判断集合是否包含指定的值
boolean c=h.containsValue(new Student("李四", 24));
System.out.println(c);
//boolean isEmpty():判断集合是否为空
boolean d=h.isEmpty();
System.out.println(d);
//获取功能
//Set<Map.Entry<K,V>> entrySet(): 返回一个键值对的Set集合
Set<Map.Entry<String, Student>> entries = h.entrySet();
System.out.println(entries);
//V get(Object key):根据键获取值
Student student=h.get("s002");
System.out.println(student);
//Set<K> keySet():获取集合中所有键的集合
Set<String> strings = h.keySet();
System.out.println(strings);
//Collection<V> values():获取集合中所有值的集合
Collection<Student> values = h.values();
System.out.println(values);
//int size():返回集合中的键值对的对数
int size=h.size();
System.out.println(size);
}
}
3,Map集合的遍历
思路1:键找值
获取所有键的集合
遍历键的集合,获取到每一个键
根据键找值
思路2:键值对对象找键和值
获取所有键值对对象的集合
遍历键值对对象的集合,获取到每一个键值对对象
根据键值对对象找键和值
public class Test {
public static void main(String[] args) {
//Map集合的遍历
//1.根据键找值
HashMap<Integer, String> map = new HashMap<>();
map.put(1,"001");
map.put(2,"002");
map.put(3,"003");
map.put(4,"004");
map.put(5,"005");
//获取键的集合
Set<Integer> integers = map.keySet();
//遍历键的集合,获取每一个键
for (Integer integer : integers) {
//根据键找值
String a=map.get(integer);
System.out.println(integer+"--"+a);
}
//2,键值对对象找键和值
//获取集合中的键值对对象的集合
Set<Map.Entry<Integer, String>> entries = map.entrySet();
//遍历键值对对象的集合,获取到每一个键值对对象
for (Map.Entry<Integer, String> entry : entries) {
/* K getKey ()
返回对应于此项的键。
V getValue ()
返回对应于此项的值。*/
Integer key = entry.getKey();
String value = entry.getValue();
System.out.println(key+"--"+value);
}
//JDK1.8 提供的遍历方式forEach()方法
map.forEach(new BiConsumer<Integer, String>() {
@Override
public void accept(Integer key, String value) {
System.out.println(key+"--"+value);
}
});
}
}
public class Test1 {
public static void main(String[] args) {
//HashMap键是自定义对象,值是String的情况
HashMap<Phone,String> hm=new HashMap<>();
hm.put(new Phone("小米",3000),"001");
hm.put(new Phone("华为",4000),"002");
hm.put(new Phone("apple",8000),"003");
hm.put(new Phone("魅族",3500),"006");
//三种方式遍历
Set<Phone> phones = hm.keySet();
for (Phone phone : phones) {
String s=hm.get(phone);
System.out.println(phone+"=="+s);
}
System.out.println("==============");
Set<Map.Entry<Phone, String>> entries = hm.entrySet();
for (Map.Entry<Phone, String> entry : entries) {
Phone p=entry.getKey();
String e=entry.getValue();
System.out.println(p+"=="+e);
}
System.out.println("---------------");
hm.forEach(new BiConsumer<Phone, String>() {
@Override
public void accept(Phone phone, String s) {
System.out.println(phone+"--"+s);
}
});
}
}
LinkedHashMap
LinkedHashMap的概述: Map 接口的哈希表和链接列表实现,具有可预知的迭代顺序
LinkedHashMap的特点: 底层的数据结构是链表和哈希表 元素有序 并且唯一
元素的有序性由链表数据结构保证 唯一性由 哈希表数据结构保证
Map集合的数据结构只和键有关
TreeMap
TreeMap: 键的数据结构是红黑树,可保证键的排序和唯一性
排序分为自然排序和比较器排序
线程是不安全的效率比较高
public class Test {
public static void main(String[] args) {
//TreeMap集合键是Student值是String的案例 按照年龄大小排序(自定义类实现Compareable接口)
TreeMap<Student, String> mm = new TreeMap<>(); 重写compareTo方法
mm.put(new Student("啤酒人",33),"肉弹冲击");
mm.put(new Student("奥巴马",23),"圣枪洗礼");
mm.put(new Student("螳螂",55),"平常恐惧");
mm.put(new Student("炼金",77),"摇啊摇");
Set<Student> students = mm.keySet();
for (Student student : students) {
String s=mm.get(student);
System.out.println(student+"=="+s);
}
}
}
public class Test1 {
public static void main(String[] args) {
//比较器排序
TreeMap<Student, String> hk = new TreeMap<>();
hk.put(new Student("啤酒人",33),"肉弹冲击");
hk.put(new Student("奥巴马",23),"圣枪洗礼");
hk.put(new Student("螳螂",55),"平常恐惧");
hk.put(new Student("炼金",77),"摇啊摇");
Set<Map.Entry<Student, String>> entries = hk.entrySet();
for (Map.Entry<Student, String> entry : entries) {
Student s=entry.getKey();
String ss=entry.getValue();
System.out.println(s+"--"+ss);
}
}
}
案例 统计字符串中每个字符出现的次数
需求:统计字符串中每个字符出现的次数
public class Test {
public static void main(String[] args) {
/* A:
案例演示:
作业:你自己先做
需求:统计字符串中每个字符出现的次数
"aababcabcdabcde", 获取字符串中每一个字母出现的次数要求结果:a(5) b(4) c(3) d(2) e(1)*/
Scanner sc = new Scanner(System.in);
System.out.println("请随便输入一段字符串");
String s = sc.nextLine();
//aaabbbcccdd 我们最后得到的字符串 a(3)b(3)c(3)d(2)
//可以用到双列集合
/*思路:1,定义一个字符串
2,定义一个Map集合
3,把字符串转换为字符数组
4,遍历字符数组,得到每一个字符
5,拿这个字符到集合中去找,看返回值
a.是null,就把该字符作为键存储,值为1;
b,不是null,就把值++,然后重新存储该键和值
6,定义一个字符串缓冲区
7,遍历TreeMap集合,获取每一个键值对拼接
8,把字符串缓冲区输出
* */
TreeMap<Character, Integer> hm = new TreeMap<>();
Set<Character> characters = hm.keySet();
char[] chars = s.toCharArray();
for (int i=0;i<s.length();i++){
char a=chars[i];
Integer j = hm.get(a);
if (j==null){
hm.put(a,1);
}else {
j++;
hm.put(a,j);
}
}
StringBuilder builder = new StringBuilder();
Set<Map.Entry<Character, Integer>> entries = hm.entrySet();
for (Map.Entry<Character, Integer> entry : entries) {
Character v=entry.getKey();
Integer num=entry.getValue();
builder.append(v+"("+num+")");
}
System.out.println(builder);
}
}
集合嵌套
public class Test {
public static void main(String[] args) {
//集合嵌套
//HashMap嵌套HashMap
/* 基础班
张三 20
李四 22
就业班
王五 21
赵六 23*/
HashMap<String, Integer> jcClass = new HashMap<>();
jcClass.put("张三",20);
jcClass.put("李四",22);
HashMap<String, Integer> jyClass = new HashMap<>();
jyClass.put("王五",21);
jyClass.put("赵六",23);
//创建一个大集合,放入两个小集合
HashMap<String, HashMap<String, Integer>> map = new HashMap<>();
map.put("基础班",jcClass);
map.put("就业班",jyClass);
System.out.println(map);
//遍历 方式1
Set<String> strings = map.keySet();
for (String string : strings) {
HashMap<String,Integer> a=map.get(string);
Set<String> strings1 = a.keySet();
System.out.println(string);
for (String s : strings1) {
Integer i=a.get(s);
System.out.println(s+"--"+i);
}
}
//方式2
Set<Map.Entry<String, HashMap<String, Integer>>> entries = map.entrySet();
for (Map.Entry<String, HashMap<String, Integer>> en : entries) {
String s=en.getKey();
System.out.println(s);
HashMap<String, Integer> minMap = en.getValue();
Set<Map.Entry<String, Integer>> ht = minMap.entrySet();
for (Map.Entry<String, Integer> node : ht) {
String s1=node.getKey();
Integer s2=node.getValue();
System.out.println("\t"+s1+"\t"+s2+"\t");
}
System.out.println();
}
}
}
public class Test1 {
public static void main(String[] args) {
//HashMap嵌套ArrayList
ArrayList<String> sg = new ArrayList<>();
sg.add("曹操");
sg.add("刘备");
ArrayList<String> sh = new ArrayList<>();
sh.add("松江");
sh.add("鲁智深");
ArrayList<String> xa = new ArrayList<>();
xa.add("令狐冲");
xa.add("林平之");
HashMap<String, ArrayList<String>> book = new HashMap<>();
book.put("三国演义",sg);
book.put("水浒传",sh);
book.put("笑傲江湖",xa);
Set<Map.Entry<String, ArrayList<String>>> entries = book.entrySet();
for (Map.Entry<String, ArrayList<String>> entry : entries) {
String key = entry.getKey();
System.out.println(key);
ArrayList<String> value = entry.getValue();
for (String s : value) {
System.out.println(s);
}
System.out.println();
}
}
}
public class Test2 {
public static void main(String[] args) {
//集合嵌套之ArrayList嵌套HashMap
HashMap<String, String> sg = new HashMap<>();
sg.put("周瑜","小乔");
sg.put("诸葛亮","黄月英");
HashMap<String, String> sd = new HashMap<>();
sd.put("郭靖","黄蓉");
sd.put("杨过","小龙女");
HashMap<String, String> xa = new HashMap<>();
xa.put("令狐冲","任盈盈");
xa.put("林平之","岳林珊");
ArrayList<HashMap<String, String>> hashMaps = new ArrayList<>();
hashMaps.add(sg);
hashMaps.add(sd);
hashMaps.add(xa);
for (HashMap<String, String> hashMap : hashMaps) {
Set<String> book = hashMap.keySet();
for (String s : book) {
String name=hashMap.get(s);
System.out.println(s+"--"+name);
}
System.out.println();
}
}
}
Collections工具类
针对集合操作 的工具类
Collections成员方法
public static <T> void sort(List<T> list): 排序,默认按照自然顺序
public static <T> int binarySearch(List<?> list,T key): 二分查找
public static <T> T max(Collection<?> coll): 获取最大值
public static void reverse(List<?> list): 反转
public static void shuffle(List<?> list): 随机置换
方法演示:
public class Test {
//Java针对 Collection 集合,提供了一个工具类Collections 为了方便的去操作 Collection 集合
public static void main(String[] args) {
ArrayList<Integer> integers = new ArrayList<>();
integers.add(100);
integers.add(20);
integers.add(500);
integers.add(50);
integers.add(1000);
//public static <T > void sort (List < T > list):排序, 默认按照自然顺序
Collections.sort(integers);
System.out.println(integers);
//public static <T > int binarySearch (List < ? > list, T key):二分查找 前提 元素有序
Integer i=Collections.binarySearch(integers,50);
System.out.println(i);
//public static <T > T max(Collection < ? > coll):获取最大值
Integer c=Collections.max(integers);
System.out.println(c);
// public static void reverse (List < ? > list):反转
Collections.reverse(integers);
System.out.println(integers);
//public static void shuffle(List<?> list) 随机打乱集合中的元素
Collections.shuffle(integers);
System.out.println(integers);
}
}
案例 模拟斗地主洗牌和发牌
public class 斗地主 {
public static void main(String[] args) {
//创建一个集合充当牌盒
ArrayList<String> box = new ArrayList<>();
//生成54张牌放进牌盒子
String[] colors={"♠","♥","♦","♣"};
String[] number={"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
//拼接形成牌
for (String color : colors) {
for (String num:number){
String poker=color.concat(num);
box.add(poker);
}
}
//手动添加大小王
box.add("JOKER1");
box.add("JOKER2");
//洗牌
Collections.shuffle(box);
//发牌 三个人斗地主,留三张底牌
ArrayList<String> 地主 = new ArrayList<>();
ArrayList<String> 农民1 = new ArrayList<>();
ArrayList<String> 农民2 = new ArrayList<>();
ArrayList<String> 底牌 = new ArrayList<>();
//方式1: 一人数个10来张发给你
// 地主=(ArrayList<String>) box.subList(0,11);
//方式二 一人一张转着发 用牌的索引对3取余
for (String poker : box) {
int num=box.indexOf(poker);
if (num>=box.size()-3){
底牌.add(poker);
}else if (num%3==0){
地主.add(poker);
}else if (num%3==1){
农民1.add(poker);
}else {
农民2.add(poker);
}
}
//看牌
lookPoker("地主",地主);
lookPoker("农民1",农民1);
lookPoker("农民2",农民2);
lookPoker("底牌",底牌);
}
private static void lookPoker(String name,ArrayList<String> list) {
System.out.println(name);
for (String poker:list){
System.out.print(poker+"\t");
}
System.out.println();
}
}
案例 模拟斗地主洗牌和发牌并对牌进行排序
public class 斗地主排序版 {
public static void main(String[] args) {
//创建一个HashMap集合充当牌盒
HashMap<Integer, String> box = new HashMap<>();
//创建一个ArrayList集合,用来存储编号
ArrayList<Integer> integers = new ArrayList<>();
//生成54张牌放进牌盒子,键为编号
String[] colors={"♠","♥","♦","♣"};
String[] nums={"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
int i=0;
for (String num:nums){
for (String color:colors){
String poker=color.concat(num);
box.put(i,poker);
integers.add(i);
i++;
}
}
//添加大小王
box.put(i,"JOKER");
integers.add(i);
i++;
box.put(i,"JOKER2");
integers.add(i);
//洗牌
Collections.shuffle(integers);
//发牌
TreeSet<Integer> 地主 = new TreeSet<>();
TreeSet<Integer> 农民1 = new TreeSet<>();
TreeSet<Integer> 农民2= new TreeSet<>();
TreeSet<Integer> 底牌= new TreeSet<>();
for (Integer num:integers){
if (num>=integers.size()-3){
底牌.add(num);
}else if (num%3==0){
地主.add(num);
}else if (num%3==1){
农民1.add(num);
}else {
农民2.add(num);
}
}
//看牌
lookPoker("地主",地主,box);
lookPoker("农民1",农民1,box);
lookPoker("农民2",农民2,box);
lookPoker("底牌",底牌,box);
}
private static void lookPoker(String name,TreeSet<Integer> t,HashMap<Integer, String> box) {
System.out.println(name);
for (Integer num : t) {
String poker=box.get(num);
System.out.print(poker+"\t");
}
System.out.println();
}
}