HashSet、LinkedHashSet、TreeSet
以下内容基于jdk1.7.0_79源码;
关于HashSet、LinkedHashSet、TreeSet
Set接口的实现类,最大特点是不允许出现重复元素;
HashSet:基于HashMap实现,一个性能相对较好的Set;
LinkedHashSet:基于LinkedHashMap实现,一个保存了插入顺序的Set;
TreeSet;基于TreeSet实现,一个实现了排序的Set;
类图关系
源码分析
Set接口的实现类相对来说都比较简单,如果熟悉HashMap、LinkedHashMap、TreeMap源码的话,HashSet、LinkedHashSet、TreeSet的代码会很好理解,因为基本上都是调用对应Map的方法来实现的;
HashSet部分源码:
package java.util;
public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
{
static final long serialVersionUID = -5024744406713321676L; //存储元素的HashMap
private transient HashMap<E,Object> map; // 一个冗余的空对象,用于在Map中存放key对应的value,Map中所有的键值对的value都是同一个空Object的引用
private static final Object PRESENT = new Object(); /**
* 构造方法,直接生成一个对应的HashMap
*/
public HashSet() {
map = new HashMap<>();
} //省略一部分代码..... //返回HashMap的key迭代器,HashSet中的元素实际上就是HashMap中的key元素
public Iterator<E> iterator() {
return map.keySet().iterator();
} //调用HashMap的put方法,将e-PRESENT键值对对象put到map中
public boolean add(E e) {
return map.put(e, PRESENT)==null;
} //省略一部分代码.....
}
LinkedHashMap源码,如下,代码很少,主要是构造方法,
根据传入的参数,调用父类HashSet的HashSet(int initialCapacity, float loadFactor, boolean dummy)方法,生成一个LinkedHashMap对象存储集合元素:
package java.util;
public class LinkedHashSet<E>
extends HashSet<E>
implements Set<E>, Cloneable, java.io.Serializable { private static final long serialVersionUID = -2851667679971038690L; public LinkedHashSet(int initialCapacity, float loadFactor) {
super(initialCapacity, loadFactor, true);
} public LinkedHashSet(int initialCapacity) {
super(initialCapacity, .75f, true);
} public LinkedHashSet() {
super(16, .75f, true);
} public LinkedHashSet(Collection<? extends E> c) {
super(Math.max(2*c.size(), 11), .75f, true);
addAll(c);
}
}
HashSet中生成LinkedHashMap的构造方法HashSet(int initialCapacity, float loadFactor, boolean dummy)
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<>(initialCapacity, loadFactor);
}
TreeSet部分源码:
有一个NavigableMap类型的Map和一个空对象,NavigableMap会在构造方法里被赋成一个TreeMap对象,PRESENT是所有键值对中value对象的同一个引用;
public class TreeSet<E> extends AbstractSet<E>
implements NavigableSet<E>, Cloneable, java.io.Serializable
{
/**
* TreeMap对象
*/
private transient NavigableMap<E,Object> m; // 空对象,所有Map键值对中value对象的同一个引用
private static final Object PRESENT = new Object();
构造方法,可见TreeSet是基于TreeMap实现的:
TreeSet(NavigableMap<E,Object> m) {
this.m = m;
} public TreeSet() {
this(new TreeMap<E,Object>());
}
再看其它TreeSet中方法的源码,基本都是通过调用TreeMap的方法实现;
//省略部分代码。。。
public NavigableSet<E> descendingSet() {
return new TreeSet<>(m.descendingMap());
}
public int size() {
return m.size();
} public boolean isEmpty() {
return m.isEmpty();
}
//省略部分代码。。。
补充一句
学好Set集合的关键是把Map学好。
HashSet、LinkedHashSet、TreeSet的更多相关文章
- 规则集之探究何时使用HashSet、LinkedHashSet以及TreeSet?
前言 Java集合框架三种主要类型的集合:规则集(Set).线性表(List).队列(Queue).Set用来存储不可重复的元素:List用来存储有元素构成的有序的集合:而Queue则用于存储用先进先 ...
- Java集合框架(二)—— HashSet、LinkedHashSet、TreeSet和EnumSet
Set接口 前面已经简绍过Set集合,它类似于一个罐子,一旦把对象'丢进'Set集合,集合里多个对象之间没有明显的顺序.Set集合与Collection基本上完全一样,它没有提供任何额外的方法. Se ...
- 一、集合框架(关于ArrayList,LinkedList,HashSet,LinkedHashSet,TreeSet)
一.ArrayList 解决了数组的局限性,最常见的容器类,ArrayList容器的容量capacity会随着对象的增加,自动增长.不会出现数组边界的问题. package collection; ...
- Java集合系列(三):HashSet、LinkedHashSet、TreeSet的使用方法及区别
本篇博客主要讲解Set接口的三个实现类HashSet.LinkedHashSet.TreeSet的使用方法以及三者之间的区别. 注意:本文中代码使用的JDK版本为1.8.0_191 1. HashSe ...
- Java中的集合HashSet、LinkedHashSet、TreeSet和EnumSet(二)
Set接口 前面已经简绍过Set集合,它类似于一个罐子,一旦把对象'丢进'Set集合,集合里多个对象之间没有明显的顺序.Set集合于Collection基本上完全一样,它没有提供任何额外的方法. Se ...
- Java自学-集合框架 HashSet、LinkedHashSet、TreeSet之间的区别
HashSet. LinkedHashSet.TreeSet之间的区别 步骤 1 : HashSet LinkedHashSet TreeSet HashSet: 无序 LinkedHashSet: ...
- Java Set 常用集合 HashSet、LinkedHashSet、TreeSet
Java 中的 Set 是非常常用的数据类型.Set 是无序的 Collection,Java Set 有三个常用的实现类,分别是:HashSet.LinkedHashSet.TreeSet 本文基于 ...
- 09 Collection,Iterator,List,listIterator,Vector,ArrayList,LinkedList,泛型,增强for,可变参数,HashSet,LinkedHashSet,TreeSet
09 Collection,Iterator,List,listIterator,Vector,ArrayList,LinkedList,泛型,增强for,可变参数,HashSet,LinkedHas ...
- HashSet、LinkedHashSet、TreeSet 简明解释
HashSet:元素无序.比如存入a.e.c.d.b,输出d.e.b.c.a. LinkedHashSet:怎么存进去,怎么出来.比如存入a.e.c.d.b,输出a.e.c.d.b. TreeSet: ...
随机推荐
- C++宏和枚举
宏 我们的计算器程序,用1234对应加减乘除,对于人阅读很产生一点障碍.隔一个月后再看此代码可能想不起是0123还是1234了,还得去代码中查找,如果能为代表四则运算的四个数取个有意义的别名就好了,一 ...
- div css仿京东订单流程图样式代码
效果展示 http://hovertree.com/texiao/css/25/ 本效果适合PC,也适合移动端 手机扫描二维码查看效果: 效果图: 代码如下: <!DOCTYPE html> ...
- SQL Pretty Printer-不错的SQL格式化工具
前言 好长时间没有写过博客了,人变懒了很多,应该说本来也不怎么勤快.但今天为了这个工具,必须得勤快一下了,天下真的没有免费的午餐. 之前使用过sql server 2000的查询设计器和Toad fo ...
- cookies
Cookie[] cookies=request.getCookies(); for(Cookie c:cookies) out.println(c.getValue()+" ") ...
- java servlet+mysql全过程(原创)
前段时间写过一篇 servlet+oracle的文章,但是那是因为公司有可能接那么一个项目,然后我当时也比较闲,所以随便学了下,那玩意是白去研究了,因为公司后面并没接到那项目. 这次学servlet用 ...
- springMVC分页,interceptor实现
PageInterceptor.java @Intercepts({ @Signature(type = StatementHandler.class, method = "prepare& ...
- AngularJS例子 ng-repeat遍历输出 通过js的splice方法删除当前行
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- ThinkCMF-如何收藏
注:收藏对应的表名-cmf_user_favorites <php> $object_id = "1"; </php> <a href="{ ...
- [小北De编程手记] : Lesson 06 玩转 xUnit.Net 之 定义自己的FactAttribute
xUnit.Net本身提供了标记测试方法的标签Fact和Theory.在前面的文章<Lesson 02 玩转 xUnit.Net 之 基本UnitTest & 数据驱动>中,也对它 ...
- CSS3中DIV水平垂直居中-2(3)
用到CSS3中display的新属性. HTML <div class="parent"> </div> CSS html,body{ width: 100 ...