HashMap
关于HashMap的源码解析,笔者已经写过,这里不在重复介绍.
HashSet-集合
如果你需要判断一个集合中是否有重复的元素,那么HashSet就是最适合的集合类。
HashSet<Integer> hashSet = new HashSet<>();
hashSet.add(1);
hashSet.add(1);
hashSet.add(1);
hashSet.add(1);
System.out.println("当前集合中的元素个数为:" + hashSet.size());
当前集合中的元素个数为:1
- 如果要访问集合中的元素,需要使用迭代器进行访问。
- 对于插入集合中的元素,是不保证顺序性的。
- 这里要注意一点,HashSet是依托HashMap实现去重的,如果我们往HashSet里存放的是对象,一定要记得重写hashCode和equals方法.
实现的原理
其实不用看很多,HashSet内部声明了一个HashMap类型的变量map,每次都委托HashMap做去重.
public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
{
static final long serialVersionUID = -5024744406713321676L;
private transient HashMap<E,Object> map;
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
public boolean contains(Object o) {
return map.containsKey(o);
}
}
TreeMap-自然数排序的Map
TreeMap中的元素需要实现Comparable
(我们平时使用的包装类型自己帮我们实现了),这里我们尝试乱序插入,然后看看输出的结果
TreeMap<Integer, String> treeMap = new TreeMap<>();
treeMap.put(1, "我是1");
treeMap.put(3, "我是3");
treeMap.put(2, "我是2");
treeMap.forEach((k, v) -> System.out.println(k + "," + v));
- 输出结果
1,我是1
2,我是2
3,我是3
可以看到,key按照compare比较后的结果进行了排序.
LinkedHashMap-插入有序的Map
前面我们了解到,HashMap是无序的,但是某些场景下,我们希望元素按照插入的顺序进行读取,这个时候你就可以用上LinkedHashMap.
LinkedHashMap内部使用了一个双向链表维护了key的顺序性.
public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V>
{
/**
* The head (eldest) of the doubly linked list.
*/
transient LinkedHashMap.Entry<K,V> head;
/**
* The tail (youngest) of the doubly linked list.
*/
transient LinkedHashMap.Entry<K,V> tail;
/**
* The iteration ordering method for this linked hash map: <tt>true</tt>
* for access-order, <tt>false</tt> for insertion-order.
*
* @serial
*/
final boolean accessOrder;
// 省略
}
HashMap留了几个方法给子类进行扩展:
// Callbacks to allow LinkedHashMap post-actions
void afterNodeAccess(Node<K,V> p) { }
void afterNodeInsertion(boolean evict) { }
void afterNodeRemoval(Node<K,V> p) { }
有兴趣了解原理的,这里提供一下链接,文章只做简单的演示(因为用的确实不多,而且八股文考试很少考):
彻底理解HashMap及LinkedHashMap
- Demo
LinkedHashMap<String, String> linkedHashMap = new LinkedHashMap<>();
linkedHashMap.put("我是第一个", "111");
linkedHashMap.put("我是第二个", "222");
linkedHashMap.put("我是第三个", "333");
linkedHashMap.forEach((k, v) -> System.out.println(k + ":" + v));
- 输出结果
我是第一个:111
我是第二个:222
我是第三个:333
可以看到,我们以什么顺序插入,就按什么顺序输出了结果。
总结
- Map 是一种将对象(而非数字)与对象相关联的设计,也就是key-value。
- HashMap 专为快速访问而设计,而 TreeMap 保持键始终处于排序状态,所以没有 HashMap 快。 LinkedHashMap 按插入顺序保存其元素,但使用散列提供快速访问的能力.
网友评论