Ⅰ. Map

Map是一个接口类 ,该类没有继承自 Collection,该类中存储的是 <K,V> 结构的键值对,并且 K 一定是唯一的,不能重复 。
https://docs.oracle.com/javase/8/docs/api/index.html
☠注意事项 :
-
内置类型不能直接来实例化
HashMap,必须要找其对应的包装类型 -
在
TreeMap中的key不能为空 ,否则就会抛NullPointerException异常,value可以为空;而HashMap的key和value都可以为空 。 -
Map中键值对的Key不能直接修改,value可以修改,如果要修改key,只能先将该key删除掉,然后再来进行重新插入。 -
HashMap的底层实现中,当某个桶中链表元素超过8个,并且桶的个数超过64个,此时会将该桶中的链表转化为红黑树维护 ,降低高度! -
采用方法如下所示:

-
其中
getOrDefalut()方法通常用于统计次数的时候简化代码,如下所示:public List<String> topKFrequent(String[] words, int k) { // 统计字符串出现个数 Map<String, Integer> hash = new HashMap<>(); for(int i = 0; i < words.length; ++i) { hash.put(words[i], hash.getOrDefault(words[i], 0) + 1); // 这样子来简化代码 } ... } -
Map(如HashMap、TreeMap等) 自身没有迭代器 ,即没有实现Iterator接口,但它的视图对象(keySet、entrySet、values)都可以迭代,如下所示:// 遍历 keySet()(只要 key) for (K key : map.keySet()) { System.out.println(key); } // 遍历 values()(只要 value) for (V value : map.values()) { System.out.println(value); } // 遍历 entrySet()(需要 key 和 value)⭐⭐⭐⭐⭐⭐⭐(推荐) for (Map.Entry<K, V> entry : map.entrySet()) { System.out.println(entry.getKey() + " = " + entry.getValue()); } -
上述的
entrySet()是Map接口中的一个方法,返回一个包含了所有 键值对 的Set集合 ,这些键值对就是Map.Entry<K, V>对象,它们每一个都包含两个元素:key和value。
// 也就是说上面的for-each可以转化为迭代器来处理,如下所示:(这里只举例entrySet) Iterator<Map.Entry<String, Integer>> it = map.entrySet().iterator(); while(it.hasNext()) { System.*out*.println(it.next().getKey() + " " + it.next().getValue()); } -
TreeMap和HashMap的区别如下图所示。其中因为HashMap在比较内容的时候是根据hashCode()来确定key是在哪个桶中的,而根据equals()来确定是桶中的哪个元素,所以在HashMap中存放自定义类型的时候,需要重写该自定义类型的equals()和hashCode()方法 。

Ⅱ. Set
Set 与 Map 主要的区别:
-
Set是继承自Collection的接口类 -
Set中只存储了Key。
但实际上底层源码实现是让 Set去调用 Map的接口 ,只不过传入的 value 是一个默认的 Object 对象,而只需要关心 key 即可。

常用方法如下所示:

注意事项:
-
Set最大的功能就是对集合中的元素进行去重 -
实现
Set接口的常用类有TreeSet和HashSet,还有一个LinkedHashSet,LinkedHashSet是在HashSet的基础上维护了一个双向链表来记录元素的插入次序 。 -
TreeSet中不能插入null的key,而HashSet可以。