`

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

SQL 
阅读更多

     用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 的...

    Core Java Volume I

    4. **数组和集合框架**:详述了一维和多维数组的使用,并介绍了Java集合框架,包括List(ArrayList、LinkedList)、Set(HashSet、LinkedHashSet)、Map(HashMap、TreeMap)的使用和操作。 5. **字符串处理**:...

    core java

    《核心Java》是Java编程领域中的经典教材,涵盖了Java语言的基础到高级特性,分为Volume I(基础篇)和Volume II(进阶篇)。这个压缩包包含的文件可能是这两个部分的源代码示例,有助于读者深入理解Java编程的核心...

    Core.Java练习题与编程规范

    Core Java涵盖了语言基础、集合框架、IO流、多线程、网络编程等多个核心领域,是成为一名合格Java开发者的基石。本文将围绕Core Java的练习题与编程规范展开讨论,帮助初学者更好地理解和运用Java语言。 1. **Java...

    core Java volume I英文版

    作为Core Java系列的第一卷,它主要关注Java的核心概念和技术,为读者构建坚实的编程基础。 在本书中,你可以学到以下关键知识点: 1. **Java语言基础**:了解Java的历史背景、安装Java开发环境(JDK)以及编写第...

    【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技术手册:第六版》是一本针对Java编程语言的权威指南,由安道出版社精心翻译,具有高清的页面质量,方便读者清晰查看,并且具备可复制粘贴的功能,极大地便利了学习和代码实践。本手册涵盖了Java语言的各个...

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

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

    HashSet、LInkedHashSet的使用和特点

    HashSet、LInkedHashSet的使用和特点

    Java 72 道面试题及答案.docx

    Java 集合框架是一种用于存储和管理对象的容器,主要有三种类型:Set(集)、List(列表)和 Map(映射)。集合的特点主要有两点:一是集合用于存储对象的容器,对象是用来封装数据的,对象多了也需要存储集中式管理...

    细说Java之util类.

    Java中的`util`类是Java开发中不可或缺的一部分,它们提供了许多数据结构和工具类的实现,使得开发者可以方便地处理各种数据。`java.util`包是Java标准库的核心部分,包含了许多用于处理集合、时间日期、随机数生成...

    HashSet,TreeSet和LinkedHashSet的区别1

    在Java编程语言中,集合框架是处理数据的重要工具,而Set接口是其中的一个关键部分,它不允许重复元素。本文主要探讨了三种基于Set接口的实现类:HashSet、LinkedHashSet和TreeSet,它们各自有不同的特性和使用场景...

    Java:Java学习相关代码

    Java是一种广泛使用的面向对象的编程语言,以其跨平台、高性能和强大的库支持而闻名。"Java:Java学习相关代码"的标题和描述暗示了这个压缩包可能包含了一系列用于学习Java编程的示例代码或者项目。文件名为"Java-...

    Java应用:两种Java容器类List和Set分析

    ### Java应用:两种Java容器类List和Set分析 #### 一、概述 在Java编程语言中,集合框架(Collections Framework)是处理数据的核心组件之一,它提供了存储和操作对象的各种方式。本文将深入探讨Java中的两种重要...

    Java 最常见的 208 道面试题:第二模块答案

    【Java 容器详解】 Java 容器是 Java 核心库的重要组成部分,它们提供了存储和管理对象的方式。常见的容器包括以下几类: 1. **集合接口**:主要有 Collection 和 Map 两大接口。 - **Collection**:代表一组不...

    ritelinked:LinkedHashMap和LinkedHashSet

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

Global site tag (gtag.js) - Google Analytics