1. Java Set

1. Java Set 重要观点

Java Set接口是Java Collections Framework的成员。

Set不允许出现重复元素-----------无重复

Set不保证集合中元素的顺序---------无序

Set允许包含值为null的元素,但最多只能有一个null元素。

Set支持泛型(类型的参数化),我们应尽可能使用它。将Generics与List一起使用将在运行时避免ClassCastException。

先去看Map,Set的实现类都是基于Map来实现的(如,HashSet是通过HashMap实现的,TreeSet是通过TreeMap实现的,LinkedHashSet是通过LinkedHashMap来实现的)。

2. Java Set类图

Java Set接口扩展了Collection接口。Collection接口 externs Iterable接口。

一些最常用的Set实现类是HashSet,LinkedHashSet,TreeSet,SortedSet,CopyOnWriteArraySet。

AbstractSet提供了Set接口的骨干实现,以减少实现List的工作量。

3. Java Set 方法

boolean add(E e) //如果 set 中尚未存在指定的元素,则添加此元素(可选操作)。

boolean addAll(Collection extends E> c) //如果 set 中没有指定 collection 中的所有元素,则将其添加到此 set 中(可选操作)。

void   clear() //移除此 set 中的所有元素(可选操作)。

boolean contains(Object o) //如果 set 包含指定的元素,则返回 true。

boolean containsAll(Collection> c) //如果此 set 包含指定 collection 的所有元素,则返回 true。

boolean equals(Object o) //比较指定对象与此 set 的相等性。

int    hashCode() //返回 set 的哈希码值。

boolean isEmpty() //如果 set 不包含元素,则返回 true。

Iterator iterator() //返回在此 set 中的元素上进行迭代的迭代器。

boolean remove(Object o) //如果 set 中存在指定的元素,则将其移除(可选操作)。

boolean removeAll(Collection> c) //移除 set 中那些包含在指定 collection 中的元素(可选操作)。

boolean retainAll(Collection> c) //仅保留 set 中那些包含在指定 collection 中的元素(可选操作)。

int    size() //返回 set 中的元素数(其容量)。

Object[] toArray() //返回一个包含 set 中所有元素的数组。

T[] toArray(T[] a) //返回一个包含此 set 中所有元素的数组;返回数组的运行时类型是指定数组的类型。

2. HashSet

1. HashSet 结构图

HashSet,由哈希表(实际上是一个 HashMap 实例)支持。它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。此类允许使用 null元素。!

HashSet继承了AbstractSet,实现了Cloneable和Serializable接口!

实现了Cloneable接口,即覆盖了函数clone(),实现浅拷贝。

实现了Serializable接口,支持序列化,能够通过序列化传输。

2. HashSet 重要特点

依赖于哈希表(实际上是一个 HashMap 实例)(哈希表+链表+红黑树),不可以存储相同元素(排重)

底层实现是一个HashMap(保存数据),实现Set接口。(HashSet中含有一个”HashMap类型的成员变量”map,HashSet的操作函数,实际上都是通过map实现的。)

非同步,线程不安全,存取速度快(同步封装Set s = Collections.synchronizedSet(new HashSet(...));)

默认初始容量为16。

加载因子为0.75:即当 元素个数 超过 容量长度的0.75倍 时,进行扩容

扩容增量:原容量的 1 倍,如 HashSet的容量为16,一次扩容后是容量为32

重写hashCode():HashSet集合排重时,需要判断两个对象是否相同,对象相同的判断可以通过hashCode值判断,所以需要重写hashCode()方法

重写equals():equals()方法是Object类中的方法,表示比较两个对象是否相等,若不重写相当于比较对象的地址, 所以我们可以尝试重写equals方法,检查是否排重。

会根据hashcode和equals来庞端是否是同一个对象,如果hashcode一样,并且equals返回true,则是同一个对象,不能重复存放。

fail-fast机制:HashSet通过iterator()返回的迭代器是fail-fast的。

两种遍历方法:Iterator【iterator.next()】,forEach【set.toArray();】

Set set = new HashSet();

set.add("first");

set.add("second");

set.add("three");//foreach

for(String string : set) {

System.out.println(string);

}//iterator

Iterator setIterator =set.iterator();while(setIterator.hasNext()) {

String string=(String) setIterator.next();

System.out.println(string);

}

3. TreeSet

1. TreeSet 结构图

基于 TreeMap 的 NavigableSet 实现。使用元素的自然顺序对元素进行排序,或者根据创建 set 时提供的 Comparator进行排序,具体取决于使用的构造方法。

TreeSet也不能存放重复对象,但是TreeSet会自动排序,如果存放的对象不能排序则会报错,所以存放的对象必须指定排序规则。排序规则包括自然排序和客户排序。

①自然排序:TreeSet要添加哪个对象就在哪个对象类上面实现java.lang.Comparable接口,并且重写comparaTo()方法,返回0则表示是同一个对象,否则为不同对象。

②客户排序:建立一个第三方类并实现java.util.Comparator接口。并重写方法。定义集合形式为TreeSet ts = new TreeSet(new 第三方类());

TreeSet继承了AbstractSet,实现了NavigableSet、Cloneable和Serializable接口!

继承于AbstractSet,AbstractSet实现了equals和hashcode方法。

实现了NavigableSet接口,意味着它支持一系列的导航方法。比如查找与指定目标最匹配项。

实现了Cloneable接口,即覆盖了函数clone(),实现浅拷贝。

实现了Serializable接口,支持序列化,能够通过序列化传输。

TreeSet是SortedSet接口的实现类

2. TreeSet 重要特点

依赖于TreeMap,TreeSet是基于TreeMap实现的。(红黑树)复杂度为O(log (n))

不可以存储相同元素(排重),自动排序。(有序集合)

TreeSet中不允许使用null元素!在添加的时候如果添加null,则会抛出NullPointerException异常。

TreeSet是非同步的方法【SortedSet s = Collections.synchronizedSortedSet(new TreeSet(...));】。

它的iterator 方法返回的迭代器是fail-fast的。

TreeSet不支持快速随机遍历,只能通过迭代器进行遍历! 两种遍历方法:Iterator【iterator.next()】,forEach【set.toArray();】

TreeSet中的元素支持2种排序方式:自然排序 或者 根据创建TreeSet 时提供的 Comparator 进行排序。这取决于使用的构造方法。

自然排序,重写compareTo方法:元素所属的类需要实现java.lang.Comparable接口,并重写compareTo方法。 compareTo方法除了可以进行排序外,还有排重的功能,但是必须在compareTo方法中对类中所有的属性值都进行判断,否则不比较那个属性,排重就会忽略哪个属性

定制排序,重写compare方法:元素需要通过java.util.Comparator接口(比较器)中的compare方法进行比较大小,并排序。 compare方法除了可以进行排序外,还有排重的功能,但是必须在compare方法中对类中所有的属性值都进行判断,否则不比较那个属性,排重就会忽略哪个属性

ps:Comparable中的compareTo()一个参数, Comparator中compare()两个参数,返回值都是int类型,如果返回0,表示两个比较元素相同,如果大于0 ,前面大于后面,如果小于0,前面小于后面。

3. HashSet vs TreeSet

HashSet是一个无序的集合,基于HashMap实现;TreeSet是一个有序的集合,基于TreeMap实现。

HashSet集合中允许有null元素,TreeSet集合中不允许有null元素。

HashSet和TreeSet都是非同步!在使用Iterator进行迭代的时候要注意fail-fast。

4. LinkedHashSet

1. LinkedHashSet 结构图

LinkedHashSet类:LinkedHashSet正好介于HashSet和TreeSet之间,它也是一个hash表,但它同时维护了一个双链表来记录插入的顺序,基本方法的复杂度为O(1)。

当遍历该集合时候,LinkedHashSet将会以元素的添加顺序访问集合的元素。

2. LinkedHashSet 重要特点

继承自HashSet,与HashSet唯一的区别是LinkedHashSet内部使用的是LinkHashMap((哈希表+链表+红黑树)+双向链表)。

LinkedHashSet在迭代访问Set中的全部元素时,性能比HashSet好,但是插入时性能稍微逊色于HashSet。

非同步,线程不安全,存取速度快(同步封装 Set s = Collections.synchronizedSet(new LinkedHashSet(...));)

其他同HashSet

维护插入顺序,LinkedHashSet使用LinkedHashMap对象来存储它的元素,插入到LinkedHashSet中的元素实际上是被当作LinkedHashMap的键保存起来的

LinkedHashMap的每一个键值对都是通过内部的静态类Entry实例化的。这个 Entry类继承了HashMap.Entry类。这个静态类增加了两个成员变量,before和after来维护LinkedHasMap元素的插入顺序。这两个成员变量分别指向前一个和后一个元素,这让LinkedHashMap也有类似双向链表的表现。

4. ConcurrentSkipListSet

1. ConcurrentSkipListSet 结构图

2. ConcurrentSkipListSet 重要特点

一个基于 ConcurrentSkipListMap 的可缩放并发 NavigableSet 实现。set 的元素可以根据它们的自然顺序进行排序,也可以根据创建 set 时所提供的 Comparator 进行排序,具体取决于使用的构造方法。

此实现为 contains、add、remove 操作及其变体提供预期平均 log(n) 时间开销。多个线程可以安全地并发执行插入、移除和访问操作。迭代器是弱一致 的,返回的元素将反映迭代器创建时或创建后某一时刻的 set 状态。它们不 抛出 ConcurrentModificationException,可以并发处理其他操作。升序排序视图及其迭代器比降序排序视图及其迭代器更快。

请注意,与在大多数 collection 中不同,这里的 size 方法不是 一个固定时间 (constant-time) 操作。由于这些 set 的异步特性,确定元素的当前数目需要遍历元素。此外,批量操作 addAll、removeAll、retainAll 和 containsAll 并不 保证能以原子方式 (atomically) 执行。例如,与 addAll 操作一起并发操作的迭代器只能查看某些附加元素。

此类不允许使用 null 元素,因为无法可靠地将 null 参数及返回值与不存在的元素区分开来。

4. CopyOnWriteArraySet (JUC)

1. CopyOnWriteArraySet 结构图

2. CopyOnWriteArraySet 重要特点

CopyOnWriteArraySet 是线程安全的 Set,它是由 CopyOnWriteArrayList 实现,内部持有一个 CopyOnWriteArrayList 引用,所有的操作都是由 CopyOnWriteArrayList 来实现的,区别就是 CopyOnWriteArraySet 是无序的,并且不允许存放重复值。由于是一个Set,所以也不支持随机索引元素。

适合元素比较少,并且读取操作高于更新(add/set/remove)操作的场景

由于每次更新需要复制内部数组,所以更新操作(add、set 和 remove 等等)开销比较大。

内部的迭代器 iterator 使用了不变的“快照”技术,存储了内部数组快照, 所以它的 iterator 不支持可变remove、set、add操作,但是通过迭代器进行并发读取时效率很高。

它是线程安全的。

java set复制_Java 集合系列之三:Set基本操作相关推荐

  1. java jcf查看_Java 集合系列之一:JCF集合框架概述

    容器,就是可以容纳其他Java对象的对象.Java Collections Framework(JCF)为Java开发者提供了通用的容器 java集合主要划分为四个部分: Collection(Lis ...

  2. java线程协作_java线程系列之三(线程协作)

    上一篇讲述了线程的互斥(同步),但是在很多情况下,仅仅同步是不够的,还需要线程与线程协作(通信),生产者/消费者问题是一个经典的线程同步以及通信的案例.该问题描述了两个共享固定大小缓冲区的线程,即所谓 ...

  3. LIST函数JAVA特点_Java 集合系列 07 List总结(LinkedList, ArrayList等使用场景和性能分析)...

    java 集合系列目录: 第1部分 List概括 先回顾一下List的框架图 (01) List 是一个接口,它继承于Collection的接口.它代表着有序的队列. (02) AbstractLis ...

  4. java list 博客园_Java集合系列(一)List集合

    List的几种实现的区别与联系 List主要有ArrayList.LinkedList与Vector几种实现. ArrayList底层数据结构是数组, 增删慢.查询快; 线程不安全, 效率高; 不可以 ...

  5. java字节流复制_Java使用字节流复制文件的方法

    其实用java程序复制文件并不难,具体内容如下 import java.io.FileInputStream; import java.io.FileOutputStream; import java ...

  6. java 字符串 复制_Java字符串复制

    java 字符串 复制 Sometime back I was asked how to copy a String in java. As we know that String is an imm ...

  7. java集合系列_Java集合系列01-Java集合概述

    1.Java集合基本概念 在编程中,常常需要集中存放多个数据.从传统意义上讲,数组是我们的一个很好的选择,前提是我们事先已经明确知道我们将要保存的对象的数量,因为数组长度在初始化时指定,意味着只能保存 ...

  8. java 取栈顶元素_java集合系列(7)Stack

    这篇文章开始介绍Stack.从名字看他就是一个stack,因此具有数据结构中栈的一般特性(后进先出),平时用起来相对较多一点,但是也是非常简单.这篇文章我们将从源码的角度来分析一下Stack. OK, ...

  9. java中集合怎么定义_Java集合系列(一):集合的定义及分类

    1. 集合的定义 什么是集合呢? 定义:集合是一个存放对象的引用的容器. 在Java中,集合位于java.util包下. 2. 集合和数组的区别(面试常问) 提到容器,就会想起数组,那么集合和数组的区 ...

最新文章

  1. Oracle 10GR2+ASM在OEL上的安装(VMware Server 1.0)
  2. Java Native Interface 二 JNI中对Java基本类型和引用类型的处理
  3. 738. 单调递增的数字(贪心算法)
  4. 1054. 距离相等的条形码
  5. ICCV 2019 | 上海交大MVIG团队提出InstaBoost,换个dataloader函数, COCO提升3mAP
  6. 在C#中将集合用作键
  7. 计算机组成原理2套题,计算机组成原理试卷2套含答案(大学期末复习资料).doc...
  8. RubyInstaller 在 Windows 环境下的安装
  9. html设置字体为方正小标宋,如何安装方正小标宋字体
  10. bat脚本打开cmd执行命令
  11. 世间所有,逃不过一个“缘”字
  12. 亚马逊云科技物联网产业创新峰会与你相聚蓉城
  13. 海康威视 0day_清华紫光原厂3D TLC颗粒初体验,海康威视C2000 PRO 2TB版体验
  14. Linux系统中个颜色代表
  15. 怎么提取伴奏?有什么实用的提取软件?
  16. Go语言获取中文及其他非英语字符长度
  17. 一线城市中小公司的月薪10k前端工程师应该会什么?
  18. Google Guava 工具类库
  19. 2020计算机一级考试wps分数,2020年全国计算机等级考试一级WPS Office考试大纲_圣考资料网...
  20. ES聚合查询详解(四):管道聚合

热门文章

  1. SQL学习之select into语句
  2. 牛逼顿 [转此怀念牛顿]
  3. NTKO OFFICE文档控件的卸载和安装
  4. mysql 报wait millis 60000, active 0, maxActive 50, creating 0, createErrorCount 9913 错误 解决记录
  5. 上航福州到上海航班改降虹桥机场
  6. python对《三国演义》中出现的人物出现的次数进行统计
  7. C++-题目:设计一个圆类circle和一个桌子类table,另设计一个圆桌类roundtable,它是从前两个类派生的,要求输出一个圆桌的高度,面积和颜色等数据。
  8. 现实世界里的 SOA
  9. sqlserver插入中文数据乱码
  10. 前端通过3d实现一个立体正方体