日期:2014-05-20  浏览次数:20823 次

LinkedHashSet的问题
我这理解不知道对不对,请大家看看,不对的请帮忙指正。

LinkedHashSet既有HashSet的特性,又有链表的特性,插入删除的时候体现HashSet的性能;遍历的时候有顺序,有链表的性能。

话说他要维护顺序,那插入删除的时候是不是要比单纯的HashSet要慢一些?

------解决方案--------------------
应该不会有什么差别,链表的插入删除,只是几个指针的移动。很简单的操作
------解决方案--------------------
帮顶一下 等楼下解答楼主的问题 不过个人感觉是LinkHashSet要快 有几个特性楼主可以记一下
Java code

1.允许 null 元素 但最多只能加一个 如果LinkedHashSet已经有null元素 试图再加null,不会成功,也不会抛异常。
2.当试图添加一个重复元素到LinkedHashSet时新元素并不会把旧元素替换掉 而只是新元素不会添加LinkedHashSet不会抛异常[其实第2点包括了第1点 只是因为1比较特殊单独拿出来]
3.当LinkedHashSet的容量很大时 迭代效率比同容量的HashSet要高

------解决方案--------------------
Hash也好、Link也好、List也好。

都可以理解为:为原始数据(对象)所特别组织的索引方式。按数据库来稍微理解就好了。因为在JVM中,所有的原始数据本来就是离散的,是根据内存分配情况动态给的。

所以当然可以给这些数据用上不同的索引。每种索引方式都会有其特定的优缺点和代价(跟数据库也类似)。比如数据库里一张表,你一口气给它建了不同组合的 20 几个索引,那么就意味着新增一条数据要伴随20几个索引更新动作,当然代价就高了。
------解决方案--------------------
楼主不用纠结这个问题 LinkedHashSet的出现就是要弥补HashSet不能排序的缺陷 他两都是类我们不能说某一个类因为要执行更多的功能而用时会更长 对不对
------解决方案--------------------
插入删除,是会慢些,但是,几乎感觉不到慢。
这如同你外出买药,从离开家门开始计时,
你一次买一瓶药,和一次买好几瓶要,总体时间上,感觉不出什么,无非单据上多了几行数据,
关键是出门花费在路上的时间,相对要多一些。
------解决方案--------------------
JDK的解释: 
具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现。此实现与 HashSet 的不同之外在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,即按照将元素插入到 set 中的顺序(插入顺序)进行迭代。注意,插入顺序不 受在 set 中重新插入的 元素的影响。(如果在 s.contains(e) 返回 true 后立即调用 s.add(e),则元素 e 会被重新插入到 set s 中。) 

此实现可以让客户免遭未指定的、由 HashSet 提供的通常杂乱无章的排序工作,而又不致引起与 TreeSet 关联的成本增加。使用它可以生成一个与原来顺序相同的 set 副本,并且与原 set 的实现无关: 

------解决方案--------------------
Hash是用来给数据分类的方法,其作用是尽量保证数据的均匀性,即尽量使10个数据分布于10个空间里
Set从外部看,是一个可变长数组,其长度增长有自己的规律,并非来一个新的Hash加一个元素
从单个元素看,是一个个链表,单个元素可以做到来一个加一个,线性增长
这篇文章http://wenku.baidu.com/view/f3e2793a87c24028915fc36d.html,似乎很精确地描述了HashMap的数据处理机制
这篇文章http://blog.csdn.net/wuaj1980/article/details/5538379,似乎很精确的描述了自增长数组的增长机制
------解决方案--------------------
HashSet是用HashMap来实现的,只是使用了HashMap的key。
LinkedHashSet是由LinkedHashMap来实现的。

HashMap使用数组来存放元素,数组的每一个元素都是一个链表,链表里面所有的元素的hashcode都是一样的,然后用equals来区分具体某一个元素。

LinkedHashMap和HashMap不一样的地方就在于,LinkedHashMap的Entry和HashMap的Entry不一样。
HashMap的Entry:
static class Entry<K,V> implements Map.Entry<K,V> {
final K key;
V value;
Entry<K,V> next;//指向相同hashcode的下一个元素的指针
final int hash;
}
LinkedHashMap的Entry:
private static class Entry<K,V> extends HashMap.Entry<K,V> {
Entry<K,V> before, after;//指向前一个和后一个Entry的指针
}

可以看出来,LinkedHashMap比HashMap还多了before, after,也就是用他们俩来维护插入的顺序。

LinkedHashMap和HashMap的插入删除性能基本上差不多,以删除来说,基本步骤是:先计算hashcode,找到在数组里面的位置,然后修改指针。差别在修改指针这一步,基本可以忽略。