hashmap

HashMaps with Comparable keys not working as expected

人走茶凉 提交于 2020-02-23 06:14:43
问题 We're facing weird issues with how HashMap behaves. When HashMap keys implement Comparable interface but compareTo implementation is inconsistent with equals then HashMaps: grow much larger then they are supposed to grow they contain several instances of equal elements values attached to those elements might differ get(key) result depends on which key is used (even if the keys are equal according to equals method). I've created a small test to reproduce the problem (see below). import java

JAVA - 容器详解

爷,独闯天下 提交于 2020-02-23 05:55:52
一、ArrayList 长度 可变数组 ,类似于c++ STL中的vector. 元素以 线性方式连续存储 ,内部允许存放重复元素。 允许对元素进行随机的快速访问,但是向ArrayList中 插入和删除元素的速度较慢 。 ArrayList是 非线程安全 的,若要成为线程安全,可以使用:List list=Collections.synchronizedList(new ArrayList()); 数组进行扩容时,会将老数组中的元素重新拷贝一份到新的数组中,每次数组容量的增长大约是其原容量的1.5倍。 这种操作的代价是很高的,因此在实际使用时,我们 应该尽量避免数组容量的扩张 。 当我们可预知要保存的元素的多少时,要在构造ArrayList实例时,就指定其容量,以避免数组扩容的发生。 二、LinkedList 内部采用 双向循环链表 实现,类似于c++ STL中的list. 插入和删除元素的速度较快 ,随机访问的速度较慢. LinkedList单独具有addFirst(),addLast(),getFirst(),getLast(),removeFirst()和removeLast()方法. 这些方法使得它 可以作为堆栈、队列和双向队列来 使用. LinkedList也是 非线程安全 的. 三、HashMap 基于哈希表的Map接口实现,类似于c++ STL中的unordered

各类Map实现类的性能分析

血红的双手。 提交于 2020-02-23 05:50:08
   对于Map的常用实现类而言,虽然HashMap和Hashtable的实现机制几乎一模一样,但由于Hashtable是一个古老的、线程安全的集合, 因此HashMap通常比Hashtable要快。   TreeMap通常比HashMap、Hashtable要慢(尤其在插入、删除key-value对时更慢),因为TreeMap底层采用红黑树来管理key-value 对(红黑树的每个节点就是一个key-value对)。   使用TreeMap有一个好处:TreeMap中的key-value对总是处于有序状态,无须专门进行排序操作。当TreeMap被填充之后,就可以调 用keySet(),取得由key组成的Set,然后使用toArray()方法生成key的数组,接下来使用Arrays的binarySearch()方法在已排序的数组中快速 地查询对象。   对于一般的应用场景,程序应该多考虑使用HashMap,因为HashMap正是为快速查询设计的(HashMap底层其实也是采用数组来存储 key-value对)。但如果程序需要一个总是排好的Map时,则可以考虑TreeMap。   LinkedHashMap比HashMap慢一点,因为它需要维护链表来保持Map中key-value时的添加顺序,IdentityHashMap性能没有特别出色 之处

【集合框架】JDK1.8源码分析之LinkedHashMap(二)

这一生的挚爱 提交于 2020-02-22 20:51:30
一、前言   前面我们已经分析了HashMap的源码,已经知道了HashMap可以用在哪种场合,如果这样一种情形,我们需要按照元素插入的顺序来访问元素,此时,LinkedHashMap就派上用场了,它保存着元素插入的顺序,并且可以按照我们插入的顺序进行访问。 二、LinkedHashMap用法 import java.util.Map; import java.util.LinkedHashMap; public class Test { public static void main(String[] args) { Map<String, String> maps = new LinkedHashMap<String, String>(); maps.put("aa", "aa"); maps.put("bb", "bb"); maps.put("cc", "cc"); for (Map.Entry entry : maps.entrySet()) { System.out.println(entry.getKey() + " : " + entry.getValue()); } } } View Code 说明:以上是展示LInkedHashMap简单用法的一个示例,可以看到它确实按照元素插入的顺序进行访问,保持了元素的插入顺序。更具体的用户可以去参照API。 三

【Java集合系列四】HashSet和LinkedHashSet解析

▼魔方 西西 提交于 2020-02-22 20:45:22
2017-07-29 16:58:13 一、简介 1、Set概念 Set可以理解为集合,非常类似数据概念中的集合,集合三大特征:1、确定性;2、互异性;3、无序性,因此Set实现类也有类似的特征。 2、HashSet HashSet继承自AbstractSet,实现了Set接口,但是其源码非常少,也非常简单。内部使用HashMap来存储数据,数据存储在HashMap的key中,value都是同一个默认值: 二、HashSet几个重要的方法 1、add(E e) HashSet的确定性,也可以理解为唯一性,是通过HashMap的put方法来保证的,往HashMap中put数据时,如果key是一样的,只会替换key对应的value,不会新插入一条数据。所以往HashSet中add相同的元素没有什么用,这里的相同是通过equals方法保证的,具体的在HashMap中细说。 2、remove(Object o) 简单粗暴,从HashMap中移除一条数据。 3、contains(Object o) 4、iterator() 5、其他 其他的方法诸如:size()、isEmpty()、contains()、clear()等都完全委托给了HashMap。需要注意的是:HashSet没有提供set、get等方法。 源码如下: 1 package java.util; 2 3 import java

HashMap(HashSet)的实现

白昼怎懂夜的黑 提交于 2020-02-22 20:35:58
0. HashMap(TreeMAP)、HashSet、HashTable 的关系 HashMap 的底层则维护着 Node<K, V>[] table; 一个一维数组用于快速访问(只在初次使用时进行初始化,当需要扩容时,When allocated, length is always a power of two.) static class Node<K,V> implements Map.Entry<K,V> { final int hash; // 此处的 hash 相当于 bucket final K key; V value; Node<K,V> next; // 每个节点均链接着一个链表; 在调用 get 方法返回该 key 对应的 value 时,先根据 key 对应的 hash 找到 bucket if ( (tab = table) != null && (n = tab.length) > 0 && (first = tab[(n - 1) & hash]) != null) { if (first.hash == hash && // always check first node ((k = first.key) == key || (key != null && key.equals(k)))) { return first; // 找到直接返回 } /

Java 集合 HashMap & HashSet 拾遗

牧云@^-^@ 提交于 2020-02-22 20:35:14
Java 集合 HashMap & HashSet 拾遗 @author ixenos 摘要:HashMap内部结构分析 Java HashMap采用的是冲突链表方式 从上图容易看出,如果 选择合适的散列函数, put() 和 get() 方法可以在常数时间内完成,因为较好的散列减少了散列冲突,使时间主要花在对桶寻址上(数组) ,而较少去遍历桶中的链表。但在对HashMap 进行迭代时,需要遍历整个table以及后面跟的冲突链表 。因此对于迭代比较频繁的场景,不宜将HashMap的初始大小设的过大。 有两个参数可以影响HashMap的性能:初始容量(inital capacity)和负载系数(load factor) 。初始容量指定了初始 table 的大小,负载系数用来指定自动扩容的临界值。当 entry 的数量超过 capacity*load_factor 时,容器将自动扩容并重新哈希。对于插入元素较多的场景,将初始容量设大可以减少重新哈希的次数。 将对向放入到HashMap或HashSet中时,有两个方法需要特别关心: hashCode() 和 equals() 。 hashCode() 方法决定了对象会被放到哪个 bucket 里,当多个对象的哈希值冲突时, equals() 方法决定了这些对象是否是“同一个对象” 。所以,如果要将自定义的对象放入到 HashMap 或

HashMap源码简析

痞子三分冷 提交于 2020-02-20 17:49:15
package com . example . demo . sort ; import java . io . IOException ; import java . io . InvalidObjectException ; import java . io . Serializable ; import java . lang . reflect . ParameterizedType ; import java . lang . reflect . Type ; import java . util . AbstractMap ; import java . util . Map ; import java . util . Objects ; import java . util . Set ; import java . util . AbstractSet ; import java . util . ConcurrentModificationException ; import java . util . Iterator ; import java . util . Spliterator ; import java . util . NoSuchElementException ; import java . util . Collection ;

HashMap源码详解

帅比萌擦擦* 提交于 2020-02-20 08:47:52
概述 HashMap是基于哈希表(散列表),实现Map接口的双列集合,数据结构是“链表散列”,也就是数组+链表 ,key唯一的value可以重复,允许存储null 键null 值,元素无序。 哈希表 数组:一段连续控件存储数据,指定下标的查找,时间复杂度O(1),通过给定值查找,需要遍历数组,自已对比复杂度为O(n) 二分查找插值查找,复杂度为O(logn) 线性链表:增 删除仅处理结点,时间复杂度O(1)查找需要遍历也就是O(n) 二叉树:对一颗相对平衡的有序二叉树,对其进行插入,查找,删除,平均复杂度O(logn) 哈希表:哈希表中进行添加,删除,查找等操作,性能十分之高,不考虑哈希冲突的情况下,仅需一次定位即可完成,时间复杂度为O(1)哈希表的主干就是数组 hash冲突 如果两个不同的元素,通过哈希函数得出的实际存储地址相同怎么办?也就是说,当我们对某个元素进行哈希运算,得到一个存储地址,然后要进行插入的时候,发现已经被其他元素占用了,其实这就是所谓的哈希冲突,也叫哈希碰撞。前面我们提到过,哈希函数的设计至关重要,好的哈希函数会尽可能地保证 计算简单和散列地址分布均匀,但是,我们需要清楚的是,数组是一块连续的固定长度的内存空间,再好的哈希函数也不能保证得到的存储地址绝对不发生冲突。那么哈希冲突如何解决呢?哈希冲突的解决方案有多种:开放定址法(发生冲突

JS实现HashMap

假如想象 提交于 2020-02-20 05:13:57
/** * ********* 操作实例 ************** * var map = new HashMap(); * map.put("key1","Value1"); * map.put("key2","Value2"); * map.put("key3","Value3"); * map.put("key4","Value4"); * map.put("key5","Value5"); * alert("size:"+map.size()+" key1:"+map.get("key1")); * map.remove("key1"); * map.put("key3","newValue"); * var values = map.values(); * for(var i in values){ * document.write(i+":"+values[i]+" "); * } * document.write("<br>"); * var keySet = map.keySet(); * for(var i in keySet){ * document.write(i+":"+keySet[i]+" "); * } * alert(map.isEmpty()); */ function HashMap(){ //定义长度 var length = 0; /