day04【Map集合】

Map集合

java.util.Map<K, V>是一个接口

Map不是Collection的子接口,二者无关。

  • 第一个泛型代表:键是什么类型。
  • 第二个泛型代表:值是什么类型。

二者可以相同,也可以不同
里面的方法是一对儿一对儿的数据,也叫作键值对儿。

特点:

  • 1、键不可以重复
  • 2、值可以重复
  • 3、根据键可以找到对应的值

每一对儿元素,就是一个Entry对象。
Entry是Map的一个内部子类接口。

Map的常用实现类有:

  • 1、HashMap:HashSet底层就是在复用HashMap。里面也是哈希表,速度特别快。

    2、LinkedHashMap:底层也是哈希表,但是额外还有链表,从而维护顺序。

    3、TreeMap:带有键的大小排序功能。

注意事项:

由于Map当中的key不能重复,那么就要考虑怎么确定元素对象那个是否重复?

确定两个对象是一样还是不一样:有equals和HashCode方法决定。

常用方法:

public V put(K key, V value ): 添加一个键对儿,返回被替换的本来value值。

public V remove(Object key ): 根据键删除对应的键值对儿,返回value值。

public V get(Object key ): 根据键,获取对应的value值。

public Set<K> keySet(): 获取所有的键集合。

public Collection(V) value(): 获取所有的值。

遍历Map集合的两种方式:

1、keySet(): 获取所有的键,然后再根据键获取值get方法。

2、entrySet(): 直接获取所有别的键值对儿。

Map接口当中有一个内部接口:Map.Entry<K, v>

一个Entry就代表一个键值对儿,好比是一个结婚证。
public Set<结婚证> entrySet(): 获取所有的结婚证

public Set<Entry> entrySet():

public Set<Map.Entry> entrySet():

public Set<Map.Entry<男方,女方>> entrySet():

public Set<Map.Entry<K,V>> entrySet():

可以通过entrySet方法一次性获取所有的键值对儿
- 1、得到所有的键值对儿:entrySet方法
- 2、根据键值对儿,获取键:getKey方法
- 3、根据键值对儿,获取值:getValue方法

Entry<K, V>接口当中定义的常用方法:

public K getKey(): 获取键
public K getValue(): 获取值

      // 第一个泛型代表学号
      // 第二个泛型代表姓名
      Map<String ,String> map = new HashMap<>();
      // 添加元素用put方法
      map.put("123","周星驰");
      map.put("124","周博通");
      map.put("125","周润发");
      String s = map.put("126", "周润发");
      System.out.println(s); // 返回的原来的结果,而原来没有,所以为null
      Set<String> strings = map.keySet(); // 获取所有的键值集合。
      for (String string : strings) {
          System.out.println(string+"-"+map.get(string)); // 根据键值获取value值
      }

      String remove1 = map.remove("123");
      System.out.println("删除的是:"+remove1); // 删除的是:周星驰

      String remove2 = map.remove("100");
      System.out.println(remove2); // null ,没有键值为100的数据,所以返回null

      // 通过entrySet一下获取所有的键值对儿
      Set<Map.Entry<String, String>> entries = map.entrySet();
      for (Map.Entry<String, String> entry : entries) {
          String key = entry.getKey();
          String value = entry.getValue();
          System.out.println(key+"-"+value);
      }

注意事项:

  • 如果自定义的类型,当成Map里面的value使用,那么没有任何要求。Value可以重复。
    如果自定义的类型,当做Map里面的key使用,那么key不可以重复,就必须要覆盖重写equals和hashCode。
 public static void main(String[] args) {
         Map<Integer,Student> mapA = new HashMap<>();
         mapA.put(001,new Student("迪丽热巴",18));
         mapA.put(002,new Student("古力娜扎",28));
         mapA.put(003,new Student("马尔扎哈",38));
         mapA.put(004,new Student("马尔扎哈",38));
         // {1=Student{name='迪丽热巴', age=18}, 2=Student{name='古力娜扎', age=28}, 3=Student{name='马尔扎哈', age=38}, 4=Student{name='马尔扎哈', age=38}}
         System.out.println(mapA); // 4对儿

         Map<Student ,Integer> mapB = new HashMap<>();
         mapB.put(new Student("迪丽热巴",18),001);
         mapB.put(new Student("古力娜扎",28),002);
         mapB.put(new Student("马尔扎哈",38),003);
         mapB.put(new Student("马尔扎哈",38),004);
         // 如果补充些equals和hashCode方法,依然输出四队,而键值是不能重复的,所以Student要重写equals和hashCode方法
         System.out.println(mapB); 
     }

LinkedHashMap

java.util.LinkedHashMap是HashMap的子类

里面可有哈希表,速度也比较外,但是额外还有链表,专门用来维护顺序。

 public static void main(String[] args) {
     Map<String, String> map = new LinkedHashMap<>();
     map.put("AAA", "张无忌");
     map.put("bbb", "张三丰");
     map.put("ccc", "张翠山");


     Set<Map.Entry<String, String>> entries = map.entrySet();
     for(Map.Entry<String, String> entry : entries){
         String key = entry.getKey();
         String value = entry.getValue();
         System.out.println(key+"--"+value);
     }
 }
  • 1、看get方法的返回值是不是nul
    2、containsKey方法可以直接判断是否包含键。得到boolean值。

getOrDefault方法:获取键对应的值;如果没有,那么返回第二个参数,代表默认值。

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个字符串:");
        String next = sc.next();

        // 方法一:
        // 定义一个map集合用来计算字符个数
        Map<Character, Integer> map = new HashMap<>();
        char[] chars = next.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            if (map.containsKey(chars[i])) {
                int num = map.get(chars[i]);
                num++;
                map.put(chars[i], num);
            } else {
                map.put(chars[i], 1);
            }
        }
        System.out.println(map);

        System.out.println("================");
        // 方法二
        Map<Character, Integer> mapB = new HashMap<>();

        for (int i = 0; i < next.length(); i++) {
            // 将字符串转换个单个字符
            char ch = next.charAt(i);
            // 如果有,那么返回对应的value值,第二个参数没用。
            // 如果没有,那么直接返回第二个参数,代表默认值。
            int num2 = mapB.getOrDefault(ch, 0);
            mapB.put(ch, ++num2);
        }
        System.out.println(mapB);
    }

TreeSet:

带有大小排序的功能。

TreeMap:

其中的键带有大小排序的功能。

下面两个概念要注意区分:

先后顺序,时间上先来后到。
大小排序:谁大谁小,从小到大

下面两种比较也要区分:

一不一样(相同比较器):由equals和hashCode决定。
谁大谁小(大小比较器):由Comparable或者外部指定的Comparator接口决定。

注意事项:

如果使用自定义的类型做键值,需要再自定义的类实现Coparable接口。

    public static void main(String[] args) {
        // Set本身加入的元素是无序的,而TreeSet带有大小排序
        Set<String> set = new TreeSet<>();
        set.add("AAA");
        set.add("DDD");
        set.add("BBB");
        set.add("CCC");
        System.out.println(set); // [AAA, BBB, CCC, DDD]

        System.out.println("===========");

        // TreeMap键值大小排序功能
        Map<String, String> map = new TreeMap<>();
        map.put("aaa", "bbb");
        map.put("ggg", "bbb");
        map.put("eee", "bbb");
        map.put("sss", "bbb");
        System.out.println(map); // {aaa=bbb, eee=bbb, ggg=bbb, sss=bbb}

        // 运用TreeMap把自定义的对象作为键值进行大小排序
        Map<Person, String> map2 = new TreeMap<>();
        map2.put(new Person("鹿晗", 24), "shit");
        map2.put(new Person("吴亦凡", 23), "shit");
        // 如果Person不去继承Comparable类设置大小关系,会报 :ClassCastException
        Set<Map.Entry<Person,String>> entries = map2.entrySet();
        for (Map.Entry<Person, String> entry : entries) {
            Person key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key+"--"+value);
        }
    }

静态方法of:

从Java9开始,集合的接口当中添加了静态方法of,用来快速生成集合

注意事项:

通过这种方式创建出来的集合,是不可变集合。

如果尝试改变集合当中的内容,那么会发生:UnsuporttedOperationException。

    public static void main(String[] args) {
        List<String> list = List.of("java", "groovy", "kotlin", "scala");
//        list.add("php"); // UnsupportedOperationException
        System.out.println(list); // [java, groovy, kotlin, scala]

        // 对于Set集合来说,如果有重复元素,将会发生IllegalArgumentException异常。
        Set<String> set = Set.of("java", "groovy", "kotlin"/*,"java"*/);
        System.out.println(set); // [groovy, kotlin, java]

        Map<String, String> map = Map.of("王宝强", "马蓉", "贾乃亮", "李小璐");
        System.out.println(map); // {王宝强=马蓉, 贾乃亮=李小璐}
    }

Map集合的概述
这里写图片描述
Entry的概念
这里写图片描述
Map统计字符出现的顺序
这里写图片描述
斗地主的排序案例分析
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值