Java 集合 -- Map

使用 Map

在 java 集合中,Map 并不在接口 Collection 之中。

接口 Map 的常用实现类有:

  • EnumMap 类

  • HashMap 类

  • TreeMap 类(TreeMap 是接口 SortedMap 的实现类,接口 SortedMap 是 Map 的子接口

  • Properties 类等

Map是一种键值(key-value)映射表的数据结构,作用就是能高效通过key快速查找value(元素)。

Map 的实现类:HashMap

HashMap是一种通过对key计算hashCode(),通过空间换时间的方式,直接定位到value所在的内部数组的索引,因此,查找效率非常高。

用HashMap来实现根据name查询某个Student的代码如下:

public class MapMain {
    public static void main(String[] args){
        Student student = new Student("xiao ming",99);
        HashMap<String, Student> map = new HashMap<>();
        // 将 "xiao ming"与Student 实例映射起来
        map.put("xiao ming", student);
        // // 通过key查找并返回映射的Student实例
        Student target = map.get("xiao ming");

        System.out.println(target == student);
        System.out.println(target.score);
        Student bob = map.get("Bob");
        System.out.println(bob);
    }

    static class Student{ // static 不可或缺
        public String name;
        public int score;

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

通过上述代码可知:Map<K, V>是一种键-值映射表,当我们调用put(K key, V value)方法时,就把key和value做了映射并放入Map。当我们调用V get(K key)时,就可以通过key获取到对应的value。如果key不存在,则返回null。

和List类似,Map也是一个接口,最常用的实现类是HashMap。

始终牢记:Map中不存在重复的key,因为放入相同的key,只会把原有的key-value对应的value给替换掉。

此外,在一个Map中,虽然key不能重复,但value是可以重复的:

Map<String, Integer> map = new HashMap<>();
map.put("apple", 123);
map.put("pear", 123); // ok

遍历 Map

对Map来说,要遍历key可以使用增强for循环遍历Map实例的keySet()方法返回的Set集合,它包含不重复的key的集合:

public static void main(String[] args){
        HashMap<String, Integer> map = new HashMap<>();
        map.put("apple", 124);
        map.put("pear", 345);
        map.put("banana", 567);
        for (String key:map.keySet()){
            Integer value = map.get(key);
            System.out.println(key + "=" + value);
        }
    }

同时遍历key和value可以使用增强for循环遍历Map对象的entrySet()集合,它包含每一个key-value映射:

public static void main(String[] args){
        HashMap<String, Integer> map = new HashMap<>();
        map.put("apple", 123);
        map.put("pear", 456);
        map.put("banana", 789);
        for (Map.Entry<String, Integer> entry:map.entrySet()){
            String key = entry.getKey();
            Integer value = entry.getValue();
            System.out.println(key + "=" + value);
        }
    }

Map和List不同的是,Map存储的是key-value的映射关系,并且,它不保证顺序

在遍历的时候,遍历的顺序既不一定是put()时放入的key的顺序,也不一定是key的排序顺序。使用Map时,任何依赖顺序的逻辑都是不可靠的。

Map 的实现类 EnumMap

如果作为key的对象是enum类型,那么,还可以使用Java集合库提供的一种EnumMap,它在内部以一个非常紧凑的数组存储value,并且根据enum类型的key直接定位到内部数组的索引,并不需要计算hashCode(),不但效率最高,而且没有额外的空间浪费。

我们以DayOfWeek这个枚举类型为例,为它做一个“翻译”功能:

public class Main {
    public static void main(String[] args) {
        Map<DayOfWeek, String> map = new EnumMap<>(DayOfWeek.class);
        map.put(DayOfWeek.MONDAY, "星期一");
        map.put(DayOfWeek.TUESDAY, "星期二");
        map.put(DayOfWeek.WEDNESDAY, "星期三");
        map.put(DayOfWeek.THURSDAY, "星期四");
        map.put(DayOfWeek.FRIDAY, "星期五");
        map.put(DayOfWeek.SATURDAY, "星期六");
        map.put(DayOfWeek.SUNDAY, "星期日");
        System.out.println(map);
     System.out.println(map.get(DayOfWeek.MONDAY));
    }
}
小结
  • 如果Map的key是enum类型,推荐使用EnumMap,既保证速度,也不浪费空间。

  • 使用EnumMap的时候,根据面向抽象编程的原则,应持有Map接口。

使用TreeMap

TreeMap 是接口 SortedMap 的实现类,而接口 SortedMap是接口 Map 的子接口。

SortedMap保证遍历时以Key的顺序来进行排序。

例如,放入的Key是"apple"、"pear"、"orange",遍历的顺序一定是"apple"、"orange"、"pear",因为String默认按字母排序:

public class Main {
    public static void main(String[] args) {
        Map<String, Integer> map = new TreeMap<>();
        map.put("orange", 1);
        map.put("apple", 2);
        map.put("pear", 3);
        for (String key : map.keySet()) {
            System.out.println(key);
        }
        // apple, orange, pear
    }
}

使用TreeMap时,放入的Key必须实现Comparable接口

String、Integer这些类已经实现了Comparable接口,因此可以直接作为Key使用。作为Value的对象则没有任何要求。

下图是已经实现了Comparable接口的类:

每天学习一点点,每天进步一点点。

原文地址:https://www.cnblogs.com/youcoding/p/13418614.html