`
这些年
  • 浏览: 400376 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

zy19982004--容器学习六:HashSet & LinkedHashSet & TreeSet源码分析

 
阅读更多

一.概述

     Set是通过Map来支持的,Set接口里的所有方法,都委托给内部的Map去实现。

 

二.HashSet源码

Java代码  收藏代码
  1. public class HashSet<E>  
  2.     extends AbstractSet<E>  
  3.     implements Set<E>, Cloneable, java.io.Serializable  
  4. {  
  5.     static final long serialVersionUID = -5024744406713321676L;  
  6.   
  7.     //内部保存一个map引用  
  8.     private transient HashMap<E,Object> map;  
  9.   
  10.     //此static final的Object来充当map的value  
  11.     private static final Object PRESENT = new Object();  
  12.   
  13.     //构造函数里面初始化一个map  
  14.     public HashSet() {  
  15.     map = new HashMap<E,Object>();  
  16.     }  
  17.   
  18.     public HashSet(Collection<? extends E> c) {  
  19.     map = new HashMap<E,Object>(Math.max((int) (c.size()/.75f) + 116));  
  20.     addAll(c);  
  21.     }  
  22.   
  23.     public HashSet(int initialCapacity, float loadFactor) {  
  24.     map = new HashMap<E,Object>(initialCapacity, loadFactor);  
  25.     }  
  26.   
  27.     public HashSet(int initialCapacity) {  
  28.     map = new HashMap<E,Object>(initialCapacity);  
  29.     }  
  30.     //此构造函数不是public的  
  31.     //它初始化了一个LinkedHashMap,可以猜到LinkedHashSet继承了HashSet  
  32.     //HashSet靠HashMap实现,LinkedHashSet靠LinkedHashMap实现,HashSet和LinkedHashSet提供一样的方法  
  33.     //LinkedHashSet继承HashSet + 这里的构造函数 = LinkedHashSet只需要构造函数,不需要任何其它代码了  
  34.     HashSet(int initialCapacity, float loadFactor, boolean dummy) {  
  35.     map = new LinkedHashMap<E,Object>(initialCapacity, loadFactor);  
  36.     }  
  37.   
  38.     //迭代Key  
  39.     public Iterator<E> iterator() {  
  40.     return map.keySet().iterator();  
  41.     }  
  42.   
  43.     public int size() {  
  44.     return map.size();  
  45.     }  
  46.   
  47.     public boolean isEmpty() {  
  48.     return map.isEmpty();  
  49.     }  
  50.   
  51.     //o就是map里面的key  
  52.     public boolean contains(Object o) {  
  53.     return map.containsKey(o);  
  54.     }  
  55.     //添加数据给map去实现就好了,返回boolean  
  56.     public boolean add(E e) {  
  57.     return map.put(e, PRESENT)==null;  
  58.     }  
  59.   
  60.     //删除数据给map去实现就好了返回boolean  
  61.     public boolean remove(Object o) {  
  62.     return map.remove(o)==PRESENT;  
  63.     }  
  64.   
  65.     public void clear() {  
  66.     map.clear();  
  67.     }  
  68.   
  69.     //clone出一个newSet,给此newSet的成员变量map赋值  
  70.     public Object clone() {  
  71.     try {  
  72.         HashSet<E> newSet = (HashSet<E>) super.clone();  
  73.         newSet.map = (HashMap<E, Object>) map.clone();  
  74.         return newSet;  
  75.     } catch (CloneNotSupportedException e) {  
  76.         throw new InternalError();  
  77.     }  
  78.     }  
  79.   
  80.     //依然是序列化map里面存放的对象  
  81.     private void writeObject(java.io.ObjectOutputStream s)  
  82.         throws java.io.IOException {  
  83.     // Write out any hidden serialization magic  
  84.     s.defaultWriteObject();  
  85.   
  86.         // Write out HashMap capacity and load factor  
  87.         s.writeInt(map.capacity());  
  88.         s.writeFloat(map.loadFactor());  
  89.   
  90.         // Write out size  
  91.         s.writeInt(map.size());  
  92.   
  93.     // Write out all elements in the proper order.  
  94.     for (Iterator i=map.keySet().iterator(); i.hasNext(); )  
  95.             s.writeObject(i.next());  
  96.     }  
  97.   
  98.     private void readObject(java.io.ObjectInputStream s)  
  99.         throws java.io.IOException, ClassNotFoundException {  
  100.     // Read in any hidden serialization magic  
  101.     s.defaultReadObject();  
  102.   
  103.         // Read in HashMap capacity and load factor and create backing HashMap  
  104.         int capacity = s.readInt();  
  105.         float loadFactor = s.readFloat();  
  106.         map = (((HashSet)thisinstanceof LinkedHashSet ?  
  107.                new LinkedHashMap<E,Object>(capacity, loadFactor) :  
  108.                new HashMap<E,Object>(capacity, loadFactor));  
  109.   
  110.         // Read in size  
  111.         int size = s.readInt();  
  112.   
  113.     // Read in all elements in the proper order.  
  114.     for (int i=0; i<size; i++) {  
  115.             E e = (E) s.readObject();  
  116.             map.put(e, PRESENT);  
  117.         }  
  118.     }  

 

三.LinkedHashSet源码

Java代码  收藏代码
  1. public class LinkedHashSet<E>  
  2.     extends HashSet<E>                //extends HashSet  
  3.     implements Set<E>, Cloneable, java.io.Serializable {  
  4.   
  5.     private static final long serialVersionUID = -2851667679971038690L;  
  6.   
  7.     public LinkedHashSet(int initialCapacity, float loadFactor) {  
  8.         super(initialCapacity, loadFactor, true);     //dummy=true  
  9.     }  
  10.   
  11.     public LinkedHashSet(int initialCapacity) {  
  12.         super(initialCapacity, .75f, true);  
  13.     }  
  14.   
  15.     public LinkedHashSet() {  
  16.         super(16, .75f, true);  
  17.     }  
  18.   
  19.      
  20.     public LinkedHashSet(Collection<? extends E> c) {  
  21.         super(Math.max(2*c.size(), 11), .75f, true);  
  22.         addAll(c);  
  23.     }  

 

四.TreeSet源码

     同HashSet一样的道理,就不贴代码了。

 

五.Set里面是否能存放null

     不必刻意去记,把前几篇分析Map的文章搞清楚了,很自然就知道了。

  1. HashMap允许插入null key,null value,所以HashSet可以插入null数据。
  2. Hashtable不允许插入null key,null value,如果一个Set用Hashtable去实现,那么这个Set不可以插入null数据。
  3. LinkedHashMap只是在HashMap基础上加了一个链表,所有的操作同HashMap,所以LinkedHashMap允许插入null key,null value,LinkedHashSet也就插入null数据。
  4. 自然顺序时TreeMap不允许插入null key,容许插入null value,所以自然顺序时TreeSet不可以插入null数据。
分享到:
评论

相关推荐

    day18-集合-中(HashSet&TreeSet&比较器).zip

    在Java编程语言中,集合框架是处理对象组的重要工具,其中`HashSet`和`TreeSet`是两种常见的接口实现类,分别提供了不同的功能和性能特性。本教程将深入探讨这两个集合类以及它们与比较器(Comparator)的关系。 ...

    HashSet,TreeSet和LinkedHashSet的区别1

    本文主要探讨了三种基于Set接口的实现类:HashSet、LinkedHashSet和TreeSet,它们各自有不同的特性和使用场景。 首先,HashSet是最基础的Set实现,它不保证元素的特定顺序,也不保证在多次操作后保持元素的顺序不变...

    02-Java集合容器面试题(2020最新版)-重点.pdf

    ### Java集合容器知识点详解 #### 一、集合容器概述 - **定义**:集合容器是Java平台提供的标准组件,主要用于存储对象。...通过本篇文章的学习,希望读者能够更好地理解和应用Java集合容器,提升编程技能。

    HashSet和TreeSet_围墙之外

    HashSet和TreeSet是Java集合框架中的两种重要数据结构,它们都是Set接口的实现类,用于存储不重复的元素。在编程实践中,理解它们的区别和应用场景至关重要。 HashSet是基于HashMap实现的,它不保证元素的顺序,...

    中华狮山面试笔记11111111

    - **Set**: HashSet、LinkedHashSet和TreeSet的特点与用途。 - **Map**: HashMap、LinkedHashMap和TreeMap的工作机制。 - **泛型**: 限制集合元素类型,提高代码安全性和可读性。 4. **并发编程** - **线程**: ...

    Java 集合常见知识点&amp;面试题总结(上),2022 最新版!.doc

    实现类有HashSet、LinkedHashSet和TreeSet。 - **Queue**:用于处理排队操作,遵循特定的入队和出队规则。实现类有LinkedList(作为双端队列)、PriorityQueue和ArrayQueue。 2. **Map接口**: - **Map**:用于...

    2024年java面试题-java集合相关面试题

    - **LinkedHashSet**:结合了HashSet和LinkedList的特性,保持元素插入顺序。 - **TreeSet**:基于红黑树实现,支持排序。 #### 3. Map - **HashMap**:基于哈希表实现,解决哈希冲突时使用链表或红黑树。 - **...

    java-all.pdf

    ### Java基础核心总结 #### 一、Java简介与环境配置 **Java** 是一种广泛使用的高级编程语言,由 Sun Microsystems 公司于1995年发布。...对于初学者而言,掌握这些基础知识是进一步学习 Java 的基石。

    Java工程师应用技术汇总

    - **HashSet**、**LinkedHashSet**、**TreeSet**:集合的不同实现。 **1.2.2 变量类型** - **基本类型**:如int、long等。 - **引用类型**:如String、Object等。 **1.2.3 String使用** - **字符串创建**:使用...

    Java集合部分面试题.docx

    - **Set**:不允许重复元素的集合,如HashSet和TreeSet,它们遵循数学上的集合概念。 - **List**:有序的集合,允许重复元素,如ArrayList和LinkedList,它们类似于可变长度的数组。 - **Map**:存储key-value对...

    Java 72道面试题和答案.docx

    - Set:无序容器,不允许元素重复,如HashSet、LinkedHashSet和TreeSet。 - Map:键值对容器,键唯一,值可重复,如HashMap、TreeMap、HashTable、LinkedHashMap和ConcurrentHashMap。 7. **底层数据结构**: - ...

    Java岗面试题大全.pdf

    LinkedHashSet (HashSet + LinkedHashmap) - **实现**:结合了`HashSet`的快速查找能力和`LinkedHashMap`的插入顺序维护能力。 - **特点**:元素按插入顺序排序。 ##### 17. HashMap (数组+链表+红黑树) - **实现*...

    Java面试必问.pdfJava面试必问.pdfJava面试必问.pdf

    - **LinkedHashSet**:保持元素插入顺序,适用于需要维护顺序的情况。 - **TreeSet**:基于红黑树实现,按自然顺序或自定义比较器排序。 - **Map**:键值对的集合,键唯一。 - **HashMap**:JDK1.8之后,由数组+...

    java资料\、文件资料、多线程和xml解析_资料汇总

    **数组** 是一种固定长度的序列容器,用于存储同类型的元素。 - **特点**:数组是 `Object` 对象,可以存储基本类型和对象。 - **注意事项**:多维数组实际上是一维数组的数组,因此不需要每维都具有相同的长度。 -...

    java集合-LinkedHashSet的使用

    有序性:LinkedHashSet 中的元素按照插入顺序进行排序,即元素被添加到集合中的顺序被记住。 唯一性:LinkedHashSet 中不允许重复元素,每个元素都必须是唯一的。如果将重复元素添加到 LinkedHashSet 中,后面的...

    java 学习笔记

    在Java学习笔记中,我们重点关注Java的IO(输入/输出)操作、常用类库以及集合框架。 1. **Java IO**: - **File类**:提供了文件和目录的基本操作,如创建、删除、重命名等。 - **RandomAccessFile**:支持对...

    java面试题题库

    - **Set**:HashSet、LinkedHashSet和TreeSet的特性及其区别。 - **Map**:HashMap、LinkedHashMap和TreeMap的工作原理及应用场景。 - **泛型**:理解泛型的基本概念,如何使用泛型限定类型参数。 5. **并发编程...

    java集合框架专题-java面试经典

    通过上述分析,我们可以看出Java集合框架提供了丰富的容器类型,每种类型的容器都有其特定的应用场景和优势。理解这些容器的特点和区别有助于在实际开发过程中选择合适的容器类型,从而提高程序的性能和效率。

    list map set区别

    - **LinkedHashSet**:继承自 HashSet,同时保持元素的插入顺序。 - **TreeSet**:基于红黑树实现的 SortedSet,提供自然排序或自定义排序功能。元素按照自然顺序或提供的比较器进行排序。 ### 深入理解 #### 1....

Global site tag (gtag.js) - Google Analytics