`

CoreJava: 第一次用LinkedHashSet带来的思考(一)

阅读更多

     用Java虽说时间不是很长,但也有将近两年, 不过这个LinkedHashSet还是第一次用, 以前只是在学Java的Collections时知道有这么个类,它可在Set的基础排重的基础上有List的保持原有顺序的作用.理解归理解,但实际中 还是一直也没遇到真正用它的场景. 在这篇博客里 ,很遗憾与这个类仅仅是擦肩而过,也没能真正地往下想想.

    在 上面那博客里提到LinkedHashSet有"排重"的作用, 其中的一个用处就是可以把List或Array中的元素放到一个HashSet里以把重复的元素去掉,不过当时没想到,用HashSet就够了, 但却为什么用了LinkedHashSet呢? 今天的一个问题逼着我想到这里LinkedHashSet的好处了: 保持List或Array里元素的顺序. 具体实例可以有: 若从数据库里取出一个List的数组, 当然可能通过SQL里的关键字distinct而在数据库里就排重,但可能出于什么特殊的考虑而没有调用distinct,这样在Java里想排重就自然 地想到了Set,而初次想到的当然也就是HashSet, 但写出来后测试时一看结果, 不对呀, 原来从数据库里取出数据明明是已Order好的, 怎么显示出的却乱了, 转念一想可不是嘛: 在用Set的HashSet排重时,它并不关心你原来数据的顺序.这时LinkedHashSet就可救火了.

    进 而往下想, LinkedHashSet内部又是怎么来保序的呢? 看LinkedHashSet的源码时,没找到答案. LinkedHashSet类里除了四个构造方法外,什么也没了. 这是怎么回事?再往下看四个构造方法中都调用了父类HashSet的构造方法, 调了又怎样呢? 难不成是HashSet也有LinkedHashSet的功能吧? 带着这个问题再看HashSet里被LinkedHashSet调用的构造方法吧, 代码如下:
          HashSet(int initialCapacity, float loadFactor, boolean dummy) {
              map = new LinkedHashMap<E,Object>(initialCapacity, loadFactor);
         }
    这 里有两个注意点,首先构造方法HashSet前没有任何访问修饰符, 也就是说只能在Java标准库里的java.util包下的类对能访问. 这也怎样呢? 下面会用到. 其次是构造方法里给map属性赋的值是一个LinkedHashMap实例. 看到这明白了: LinkedHashSet的保序功能是通过其属性LinkedHashMap实现的. 那一般的HashSet实例怎么又没有这个功能呢? 我们看HashSet的源码发现,除上面提到的那个构造方法外,它还有四个, 这四个构造方法都是public的, 在构造方法中,属性map的值都是HashMap的实例,自然也就没有Linked*所具有的保序功能了,我们所new出来的HashSet都是通过这四 个public的构造方法生成的, 自然也就没有保序功能了.

    看到这里, "保序"的实现虽说没有彻底搞明白,但知道了, 它是通过LinkedHashMap实现的, 这就不必再为
LinkedHashSet自身的实现所困惑了.如有时间再考虑人家 LinkedHashMap是怎么实现"保序"功能的.

    不过,通过这个问题的研究, 另一个设计上的启示渐渐浮出水面, LinkedHashSet在设计上又有什么启示呢?在下一篇关于LinkedHashSet的思考里将做详细的说明.

分享到:
评论
3 楼 hailong_qin 2012-09-21  
LinkedHashSet有"排重"的作用, 其中的一个用处就是可以把List或Array中的元素放到一个HashSet里以把重复的元素去掉,但是LinkedHashSet的好处: 保持List或Array里元素的顺序. 比如从数据库里取出一个List的数组, 当然可能通过SQL里的关键字distinct而在数据库里就排重,但可能出于什么特殊的考虑而没有调用distinct,这样在Java里想排重就自然地想到了Set,而初次想到的当然也就是HashSet, 但写出来后测试时一看结果, 不对呀, 原来从数据库里取出数据明明是已Order好的, 怎么显示出的却乱了, 转念一想可不是嘛: 在用Set的HashSet排重时,它并不关心你原来数据的顺序.这时LinkedHashSet 可以上场了。LinkedHashSet 顾名思义,就是在Hash的实现上添加了Linked的支持。HashSet的每个节点上通过一个链表串联起来,这样就可以保证确定的顺序。对于希望有常量复杂度的高效存取性能要求,同时有要求排序的情况下,现在可以直接使用LinkedHashSet。

2 楼 taupo 2009-02-15  
不错,我也没有用过linkedhashmap
1 楼 codeutil 2009-02-15  
java集合里的Set都是基于Map的,set相当于map里所有的key指向同一个value。
应该是花时间去学习Map的代码。

相关推荐

    java集合-LinkedHashSet的使用

    LinkedHashSet 是 Java 中的一个集合类,它是 HashSet 的子类,同时也实现了 Set 接口。与 HashSet 不同的是,LinkedHashSet 保留了元素插入的顺序,并且具有 HashSet 的快速查找特性。下面是关于 LinkedHashSet 的...

    【Java面试+Java学习指南】 一份涵盖大部分Java程序员所需要掌握的核心知识

    Java集合详解1:一文读懂ArrayList,Vector与Stack使用方法和实现原理 Java集合详解2:Queue和LinkedList Java集合详解3:Iterator,fail-fast机制与比较器 Java集合详解4:HashMap和HashTable Java集合详解5:深入...

    尚硅谷-深入Java集合5:LinkedHashSet的实现原理.pdf

    ·课程共30天,715个知识视频小节,涉及主流Java使用的方方面面,全而不冗余 ·全程内容涵盖数据结构、设计模式、JVM内存结构等深度技术 ·企业级笔试面试题目深入源码级讲解,拒绝死记硬背 4.代码量更大、案例更...

    计算机后端-Java-Java核心基础-第24章 集合01 24. LinkedHashSet的使用.avi

    计算机后端-Java-Java核心基础-第24章 集合01 24. LinkedHashSet的使用.avi

    HashSet、LInkedHashSet的使用和特点

    HashSet、LInkedHashSet的使用和特点

    ritelinked:LinkedHashMap和LinkedHashSet

    提供了LinkedHashMap和LinkedHashSet更多最新版本。 您可以在std或no_std环境中轻松使用它。 一些实用的功能组合,支持,帮助您更好地将其嵌入到现有代码: serde , inline-more等。特别是,它使用griddle在默认...

    java集合知识-map、set等

    //重复的元素只会输出一次,而且无序 f:\tang&gt; 例子4: package test; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashSet; public class HashSetDemo { public static ...

    List 去重的6种方法(contains、迭代、hashSet、treeSet、linkedHashSet、stream)

    1:contains判断去重(有序) 此方法的优点的:理解起来比较简单,并且最终得到的集合也是有序...Stream 实现去重功能和其他方法不同的是,它不用新创建集合,使用自身接收一个去重的结果就可以了,并且实现代码也很简洁

    java8源码-JavaRobot:Java学习笔记,JavaLearningNote

    java8 源码 学习笔记(持续更新中) 所有文章均同步发布到微信公众号【JavaRobot】,关注微信公众号,及时得到文章推送,谢谢支持。 说明:如无特别说明,所有代码都基于JDK8 JavaSE(Java基础) Java Core 关键字 ...

    java集合-HashSet的使用

    HashSet 是 Java 中的一个集合类,它实现了 Set 接口并提供了基于哈希表的无序、不重复元素的集合。具体来说,它是通过哈希表(实际上是一个 HashMap 实例)来存储元素的。 以下是 HashSet 的一些主要特点: 无序...

    java中set、list和map的使用方法实例

    // java中对象容器主要有Set,List和Map三个接口类。 // 迭代器(Iterator)模式,又叫做游标(Cursor)模式。 // GOF给出的定义为:提供一种方法访问一个容器...另包含一篇网文:在java中使用TreeMap进行中文排序

    Java 集合方面的面试题

    如何使用 PriorityQueue 类实现一个最小堆? 如何使用 LinkedHashSet 类来实现 LRU 缓存? 如何使用 Stream API 对集合进行过滤、映射和归约操作? 如何使用 Java 8 中的新特性 Optional 类型来处理可能为 null 的...

    Java—Set集合详解(HashSet/LinkedHashSet/TreeSet/EnumSet)

      Set集合类似于一个容器,程序把很多对象保存到Set集合中,Set集合对添加顺序不记录,当有重复的对象保存到Set集合时,不会新增后加的重复对象。 Set集合的特点 Set集合无重复元素,add()方法添加相同元素时,...

    day016-list和set笔记以及代码.zip

    总结一下: ArrayList:如果是查改多,用ArrayList LinkedList:如果是增删插多,用LinkedList Vector:如果是有线程安全要求用...LinkedHashSet:如果需要元素不重复,并且,有存入和取出顺序要求用LinkedHashSet

    Java基础知识点.html

    哈希值 LinkedHashSet TreeSet 自然排序Comparable 比较器排序Comparator Set集合 并发修改异常 LinkedList集合 ArrayList集合 List集合 Collection集合概述 冒泡排序 Object 异常 Math 包装类 Calendar类 ...

    java解析给定url

    * 现在要求用Java编写一个程序,该程序访问上面的URL,并从页面中, * 提取出上图所示位置的页面信息(仅图中所要求的内容),将其内容按如下格式,输出到控制台 * GrapWeatherInfo * @author lihsh * @version ...

    Java JDK实例宝典

    全部代码出自电子工业出版社夏先波的《Java JDK实例宝典》一书,本书以J2SE 5.0为开发环境,选取Java应用的典型实例,循序渐进地介绍了Java语言的各种开发方法和技巧,实例代码注释详细规范,思路清晰。 第1章 ...

    Java后端面试问题整理.docx

    • 熟练的使用Java语言进行面向对象程序设计,熟悉Java语言特性 • 熟悉常用排序,堆栈,树等数据结构和算法 • 熟悉常用集合数据结构(数组、Hashmap、ConcurrentHashMap、HashTable、ArrayList、Vetor、LinkedList...

    40道java集合面试题含答案(很全很详细)

    Java集合类是Java.util包中的重要内容,它提供了一套性能优良、使用方便的接口和类,用于处理对象的集合。这些类主要用于存储、检索、操作一组对象数据。 Java集合类主要包括两种类型的容器:Collection和Map。...

Global site tag (gtag.js) - Google Analytics