JavaSE学习总结(十四)Map集合Map和Collection的区别HashMapLinkedHashMapTreeMap集合间的嵌套HashtableCollections工具类

JavaSE学习总结(十四)Map集合/Map和Collection的区别/HashMap/LinkedHashMap/TreeMap/集合间的嵌套/Hashtable/Collections工具类

一、Map集合

我们知道,一个学号就能对应一个学生,并且每个学生的学号都不同,学号就像一个键,对应的学生就是该键对应的值。日常生活中经常能见到这种类似学号对应学生的例子。Java 为了我们更加方便地去操作,这种键值映射关系的数据,给我们提供了另外一种集合叫做Map集合。

(一)概述

  • public interface Map<K,V>
  • 类型参数:
    K - 此映射所维护的键的类型
    V - 映射值的类型

将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。 (键唯一,值不一定唯一)

常用子实现类:HashMapHashtableLinkedHashMapTreeMapProperties

(二)Map接口和Collection接口的区别

  • Map是双列的,Collection是单列的
  • Map的键唯一,Collection的子体系Set的元素是唯一的
  • Map集合的数据结构只针对键有效,跟值无关;Collection集合的数据结构是针对元素有效

二、HashMap集合

HashSet 用的是HashMap来存的,因此我们可以知道HashMap的键的数据结构是哈希表。

HashMap 是基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。

(一)添加功能

V put(K key,V value):添加元素。
这个方法其实还有另一个功能:替换
如果键是第一次存储,就直接存储元素,返回null
如果键不是第一次存在,就用值把以前的值替换掉,返回被替换的值

案例演示1

import java.util.HashMap;

public class MyTest {
    public static void main(String[] args) {
        HashMap<String, String> map = new HashMap<>();
        map.put("Monday","星期一");
        map.put("Tuesday","星期二");
        map.put("Wednesday","星期三");
        map.put("Thursday","星期四");
        map.put("Friday","星期五");
        map.put("Saturday","星期六");
        map.put("Sunday","星期日");
        System.out.println(map);
        //当发生键相同的时候,值就会覆盖,返回的是旧值
        String s = map.put("Today", "今天");
        String s1 = map.put("Today", "今日");
        System.out.println(s);
        System.out.println(s1);
    }
}

在这里插入图片描述
案例演示2
键是 String 类型 值是Student类型

import java.util.HashMap;

//学生类
class Student {
    private String name;
    private int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    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 +
                '}';
    }
}

//测试类
public class MyTest {
    public static void main(String[] args) {
        HashMap<String, Student> map = new HashMap<>();
        map.put("001",new Student("张三",23));
        map.put("001",new Student("李四",23));
        map.put("002",new Student("王五",22));
        map.put("003",new Student("赵六",21));
        System.out.println(map);
    }
}

如果String类型的键存在重复的,只会存最后出现那个(覆盖)
在这里插入图片描述

案例演示3
键是Student类型 值是String类型

import java.util.HashMap;

public class MyTest {
    public static void main(String[] args) {
        HashMap<Student, String> map = new HashMap<>();
        map.put(new Student("张三",23),"001");
        map.put(new Student("张三",23),"002");
        map.put(new Student("王五",22),"003");
        map.put(new Student("赵六",21),"004");
        System.out.println(map);
    }
}

在这里插入图片描述
如果Student类型的键的内容存在重复,而都能存进去,这是为什么呢?因为每创建一个Student对象,地址值是不同的,即使元素相同。而如果我们重写了Student类的equals()方法和hashCode()方法就能做到不存重复的键。

(二)删除功能

void clear():移除所有的键值对元素
V remove(Object key):根据键删除键值对元素,并把值返回

案例演示

import java.util.HashMap;

public class MyTest {
    public static void main(String[] args) {
        HashMap<Integer, String> hashMap = new HashMap<>();
        hashMap.put(1,"aaa");
        hashMap.put(2, "ccc");
        hashMap.put(3, "ddd");
        hashMap.put(4, "eee");
        hashMap.put(5, "fff");
        //根据键移除这个键值对
        hashMap.remove(4);//移除键为4的键值对
        System.out.println(hashMap);
        //清空集合中所有的元素
        hashMap.clear();
        System.out.println(hashMap);
    }
}

在这里插入图片描述

(三)判断功能

boolean containsKey(Object key):判断集合是否包含指定的键
boolean containsValue(Object value):判断集合是否包含指定的值
boolean isEmpty():判断集合是否为空
案例演示

import java.util.HashMap;

public class MyTest {
    public static void main(String[] args) {
        HashMap<Integer, String> hashMap = new HashMap<>();
        hashMap.put(1, "aaa");
        hashMap.put(1, "bbb");
        hashMap.put(2, "ccc");
        hashMap.put(3, "ddd");
        hashMap.put(4, "eee");
        hashMap.put(5, "fff");
        // HashMap允许使用 null 值和 null 键
        hashMap.put(null,null);
        System.out.println(hashMap.get(null));

        //判断集合有没有1这个键
        boolean b = hashMap.containsKey(1);
        System.out.println(b);
        //判断集合中有没有bbb这个值
        boolean flag = hashMap.containsValue("bbb");
        System.out.println(flag);
        //判断集合是否为空
        boolean b1 = hashMap.isEmpty();
        System.out.println(b1);
    }
}

在这里插入图片描述

(四)获取功能

Set<Map.Entry<K,V>> entrySet(): 返回一个键值对对象的Set集合
V get(Object key):根据键获取值
Set<K> keySet():获取集合中所有键的集合
Collection<V> values():获取集合中所有值的集合

案例演示

  • 遍历Map集合方式1
import java.util.HashMap;
import java.util.Set;

public class MyTest {
    public static void main(String[] args) {
        HashMap<Integer, String> hashMap = new HashMap<>();
        hashMap.put(1, "bbb");
        hashMap.put(2, "ccc");
        hashMap.put(3, "ddd");
        hashMap.put(4, "eee");
        hashMap.put(5, "fff");
        //获取集合中所有键的集合
        Set<Integer> set = hashMap.keySet();
        for (Integer key : set) {
            System.out.println(key+"="+hashMap.get(key)); // V get(Object key):根据键获取值
        }
    }
}

在这里插入图片描述

  • 遍历Map集合方式2
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class MyTest {
    public static void main(String[] args) {
        HashMap<Integer, String> hashMap = new HashMap<>();
        hashMap.put(1, "bbb");
        hashMap.put(2, "ccc");
        hashMap.put(3, "ddd");
        hashMap.put(4, "eee");
        hashMap.put(5, "fff");
        //entrySet() 获取键值对 对象 放到Set集合里面去
        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);
        }
    }
}

在这里插入图片描述

(五)长度功能

int size():返回集合中的键值对的对数
案例演示

import java.util.HashMap;

public class MyTest {
    public static void main(String[] args) {
        HashMap<Integer, String> hashMap = new HashMap<>();
        hashMap.put(1, "bbb");
        hashMap.put(2, "ccc");
        hashMap.put(3, "ddd");
        hashMap.put(4, "eee");
        hashMap.put(5, "fff");
        System.out.println(hashMap.size());
    }
}

在这里插入图片描述

三、LinkedHashMap集合

  • LinkedHashMap的底层的数据结构是链表和哈希表,元素有序(存取顺序一致)并且唯一
  • 元素的有序性由链表数据结构保证;唯一性由哈希表数据结构保证
  • 允许 null 元素

注意:Map集合的数据结构只和键有关
案例演示

import java.util.LinkedHashMap;
import java.util.Set;

public class MyTest{
    public static void main(String[] args) {
        //键的数据结构是链表和哈希表,链表保证键有序,哈希表保证键唯一
        LinkedHashMap<String, String> linkedHashMap = new LinkedHashMap<>();
        linkedHashMap.put("aaa", "AAA");
        linkedHashMap.put("aaa", "AAA2");
        linkedHashMap.put("ccc", "CCC");
        linkedHashMap.put("ddd", "DDD");
        linkedHashMap.put("eee", "EEE");
        Set<String> strings = linkedHashMap.keySet();
        for (String key : strings) {
            System.out.println(key + "===" + linkedHashMap.get(key));
        }
    }
}

在这里插入图片描述

四、TreeMap集合

  • TreeMap的数据结构是红黑树,可保证键的排序和唯一性
  • 排序分为自然排序和比较器排序
  • 线程是不安全的效率比较高
  • TreeMap 键不允许插入null

案例演示1
键是Integer类,值是String类

import java.util.Set;
import java.util.TreeMap;

public class MyTest {
    public static void main(String[] args) {
        TreeMap<Integer, String> treeMap = new TreeMap<>();
        treeMap.put(10,"aaaa");
        treeMap.put(100, "bbbb");
        treeMap.put(1, "cccc");
        treeMap.put(0, "dddd");
        treeMap.put(1044, "eeee");
        treeMap.put(1088, "ffff");

        Set<Integer> integers = treeMap.keySet();
        for (Integer integer : integers) {
            System.out.println(integer+"=="+treeMap.get(integer));
        }
    }
}

在这里插入图片描述

案例演示2
键是String类,值是Integer类

import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

public class MyTest{
    public static void main(String[] args) {
        TreeMap<String, Integer> treeMap = new TreeMap<>();
        treeMap.put("aaa", 111);
        treeMap.put("ggg", 1110);
        treeMap.put("d", 1119);
        treeMap.put("sss", 1114);
        treeMap.put("c", 1141);
        treeMap.put("fff", 1161);
		//同样也能实现排序,因为String也实现了Comparable接口并重写了compareTo()方法
        Set<Map.Entry<String, Integer>> entries = treeMap.entrySet();
        for (Map.Entry<String, Integer> entry : entries) {
            String key = entry.getKey();
            Integer value = entry.getValue();
            System.out.println(key+"==="+value);
        }
    }
}

在这里插入图片描述
案例演示3
键是自定义的Student类,值是String类
自然排序:需要Student类实现Comparable接口并重写compareTo()方法

import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
//学生类
class Student implements Comparable<Student>{
    private String name;
    private int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    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 int compareTo(Student o) {
        int num=this.age-o.age;
        int num2=num==0?this.name.compareTo(o.name):num;
        return num2;
    }
}
public class MyTest {
    public static void main(String[] args) {
        TreeMap<Student, String> treeMap = new TreeMap<>();
        treeMap.put(new Student("张三", 23), "111");
        treeMap.put(new Student("李四", 23), "222");
        treeMap.put(new Student("王五", 21), "222");
        treeMap.put(new Student("赵六", 24), "444");
        treeMap.put(new Student("赵四", 20), "555");
        treeMap.put(new Student("小明", 25), "666");
        treeMap.put(new Student("小红", 22), "777");

        Set<Map.Entry<Student, String>> entries = treeMap.entrySet();
        for (Map.Entry<Student, String> entry : entries) {
            Student key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key+"==="+value);
        }
    }
}

在这里插入图片描述
当然也可以使用比较器排序:

import java.util.Comparator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

public class MyTest {
    public static void main(String[] args) {
        TreeMap<Student, String> treeMap = new TreeMap<>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                int num=o1.getAge()-o2.getAge();
                int num2=num==0?o1.getName().compareTo(o2.getName()):num;
                return num2;
            }
        });
        treeMap.put(new Student("张三", 23), "111");
        treeMap.put(new Student("李四", 23), "222");
        treeMap.put(new Student("王五", 21), "222");
        treeMap.put(new Student("赵六", 24), "444");
        treeMap.put(new Student("赵四", 20), "555");
        treeMap.put(new Student("小明", 25), "666");
        treeMap.put(new Student("小红", 22), "777");

        Set<Map.Entry<Student, String>> entries = treeMap.entrySet();
        for (Map.Entry<Student, String> entry : entries) {
            Student key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key+"==="+value);
        }
    }
}

在这里插入图片描述


思考题:输入一个英文字符串,输出每个字母出现的次数。

import java.util.*;

public class MyTest {
    public static void main(String[] args) {
        System.out.println("请输入字符串:");
        Scanner sc = new Scanner(System.in);
        String s = sc.next();
        TreeMap<Character, Integer> map = new TreeMap<>();
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if(!map.containsKey(c)){ //如果map集合不存在这个键,就加进去
                map.put(c,1); //1表示c代表的字符出现一次
            }else{ //如果map集合已经存在这个键
                Integer integer = map.get(c);//就将这个键对应的值取出来加一
                integer++;
                map.put(c,integer);//再放进集合中,由于键相同,它会覆盖之前的
            }
        }
        Set<Map.Entry<Character, Integer>> entries = map.entrySet();
        for (Map.Entry<Character, Integer> entry : entries) {
            System.out.println(entry.getKey()+"出现的次数是:"+entry.getValue());
        }
    }
}

在这里插入图片描述

五、集合间的嵌套

(一)HashMap嵌套HashMap

案例演示

普通班
		张三	20
		李四	22
尖子班
		王五	21
		赵六	23

解析:每个班是键,班里的同学信息是对应的值;而同学的名字又是键,同学的年龄是对应的值。

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class MyTest1 {
    public static void main(String[] args) {
        HashMap<String, Integer> ptb = new HashMap<>();
        ptb.put("张三",20);
        ptb.put("李四",22);
        HashMap<String, Integer> jzb = new HashMap<>();
        jzb.put("王五",21);
        jzb.put("赵六",23);

        HashMap<String, HashMap<String, Integer>> classMap= new HashMap<>();
        classMap.put("普通班",ptb);
        classMap.put("尖子班",jzb);

        //遍历
        Set<String> strings = classMap.keySet();
        for (String string : strings) {
            System.out.println(string);
            HashMap<String, Integer> map = classMap.get(string);
            Set<Map.Entry<String, Integer>> entries = map.entrySet();
            for (Map.Entry<String, Integer> entry : entries) {
                System.out.println("\t"+entry.getKey()+" "+entry.getValue());
            }
        }
    }
}

在这里插入图片描述

(二)HashMap嵌套ArrayList

案例演示

三国演义
	 	吕布
	 	周瑜
笑傲江湖
	 	令狐冲
	 	林平之
神雕侠侣
	 	郭靖
	 	杨过  

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class MyTest1{
    public static void main(String[] args) {
        ArrayList<String> sanGuo = new ArrayList<>();
        sanGuo.add("吕布");
        sanGuo.add("周瑜");
        ArrayList<String> xiaoAo = new ArrayList<>();
        xiaoAo.add("令狐冲");
        xiaoAo.add("林平之");
        ArrayList<String> shenDiao = new ArrayList<>();
        shenDiao.add("郭靖");
        shenDiao.add("杨过");
        HashMap<String, ArrayList<String>> map = new HashMap<>();
        map.put("三国演义",sanGuo);
        map.put("笑傲江湖",xiaoAo);
        map.put("神雕侠侣",shenDiao);
        //遍历
        Set<Map.Entry<String, ArrayList<String>>> entries = map.entrySet();
        for (Map.Entry<String, ArrayList<String>> entry : entries) {
            System.out.println(entry.getKey());
            ArrayList<String> value = entry.getValue();
            for (String s : value) {
                System.out.println("\t"+s);
            }
        }
    }
}

在这里插入图片描述

(三)ArrayList嵌套HashMap

案例演示

周瑜---小乔
吕布---貂蝉

郭靖---黄蓉
杨过---小龙女

令狐冲---任盈盈
林平之---岳灵珊

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class MyTest1{
    public static void main(String[] args) {
        HashMap<String, String> sanGuo = new HashMap<>();
        sanGuo.put("吕布","貂蝉");
        sanGuo.put("周瑜","小乔");
        HashMap<String, String> xiaoAo = new HashMap<>();
        xiaoAo.put("令狐冲","任盈盈");
        xiaoAo.put("林平之","岳灵珊");
        HashMap<String, String> shenDiao = new HashMap<>();
        shenDiao.put("郭靖","黄蓉");
        shenDiao.put("杨过","小龙女");
        ArrayList<HashMap<String, String>> list = new ArrayList<>();
        list.add(sanGuo);
        list.add(xiaoAo);
        list.add(shenDiao);
        //遍历
        for (HashMap<String, String> map : list) {
            Set<Map.Entry<String, String>> entries = map.entrySet();
            for (Map.Entry<String, String> entry : entries) {
                System.out.println(entry.getKey()+"---"+entry.getValue());
            }
        }
    }
}

在这里插入图片描述

六、HashMap和Hashtable的区别

用法都一样
HashMap: 线程不安全,效率高,允许null值和null键
Hashtable: 线程安全,效率低,不允许null值和null键

七、Collections工具类

数组有个Arrays工具类,集合也有个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): 随机置换

案例演示

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;


public class MyTest1 {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        list.add(100);
        list.add(1002);
        list.add(1030);
        list.add(1050);
        list.add(1040);
        //list.sort();

        //升序排序
        Collections.sort(list);
        //降序排序
        //Collections.sort(list, new Comparator<Integer>() {
        //    @Override
        //    public int compare(Integer o1, Integer o2) {
        //        return 0;
        //    }
        //});
        System.out.println(list);

        //二分查找
        int i = Collections.binarySearch(list, 1050);
        System.out.println(i);

        //最大最小值
        System.out.println(Collections.max(list));
        System.out.println(Collections.min(list));

        //反转集合中的元素
        Collections.reverse(list);
        System.out.println(list);

        //随机打乱集合中元素的顺序
        Collections.shuffle(list);
        System.out.println(list);
    }
}

在这里插入图片描述

模拟斗地主发牌洗牌整牌

import java.util.*;

public class MyTest {
    public static void main(String[] args) {
        //所有牌的集合
        //为了方便给牌排序,定义一个map集合(键是序号,值是具体牌)
        HashMap<Integer, String> pokerBox = new HashMap<>();
        //为了方便给牌排序,定义一个ArrayList集合装牌的序号
        ArrayList<Integer> indexs = new ArrayList<>();
        int index=0;
        String[] colors={"♠","♥","♦","♣"};
        String[] nums={"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
        for (String num : nums) {
            for (String color : colors) {
                pokerBox.put(index,num.concat(color));//数字拼接花色
                indexs.add(index);
                index++;
            }
        }
        pokerBox.put(index,"小王");
        indexs.add(index);
        index++;
        pokerBox.put(index,"大王");
        indexs.add(index);
        index++;

        //洗牌
        Collections.shuffle(indexs);

        //定义三位玩家(用TreeSet是因为存牌的序号进去自然就排好序了)
        TreeSet<Integer> duWang = new TreeSet<>();
        TreeSet<Integer> duShen = new TreeSet<>();
        TreeSet<Integer> duXia = new TreeSet<>();
        //定义三张地主底牌
        TreeSet<Integer> diPai = new TreeSet<>();

        //发牌
        //赌王 0 3 6...(对3取余为0)
        //赌神 1 4 7...(对3取余为1)
        //赌侠 2 5 8...(对3取余为2)
        //底牌是最后三张
        for (int i = 0; i < indexs.size(); i++) {
            if(i>=indexs.size()-3){
                diPai.add(indexs.get(i));
            }else if(i%3==0){
                duWang.add(indexs.get(i));
            }else if(i%3==1){
                duShen.add(indexs.get(i));
            }else if(i%3==2){
                duXia.add(indexs.get(i));
            }
        }

        //看牌
        showPoker("赌王",duWang,pokerBox);
        showPoker("赌神",duShen,pokerBox);
        showPoker("赌侠",duXia,pokerBox);
        showPoker("底牌",diPai,pokerBox);
    }

    public static void showPoker(String name,TreeSet<Integer> set,HashMap<Integer,String> pokerBox){
        System.out.print(name+":");
        //以TreeSet中的数字为键,找到map里对应的值
        for (Integer integer : set) {
            System.out.print(pokerBox.get(integer)+" ");
        }
        System.out.println();
    }
}

在这里插入图片描述


集合小结
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值