集合框架1.2之Set接口

一个不包含重复元素的 collection。更确切地讲,set 不包含满足e1.equals(e2) 的元素对 e1 和 e2,并且最多包含一个 null 元素

在所有构造方法以及 add、equals 和 hashCode 方法的协定上,Set 接口还加入了其他规定,这些规定超出了从 Collection 接口所继承的内容。

Set不能包含重复的元素,它的所有方法都是从Collection接口继承的,并且对一些方法加上了相应的限制。Set还增强了equals方法和hasCode方法的可用性,允许对实现类型不一样的实例进行有意义的对比

Set接口定义的方法与Collection一致,在此不再列出,仅对Set的批量操作稍加说明。假设s1和s2都是Set类型,下面给出一些例子

s1.containsAll(s2) — 如果s2是s1的子集,返回true;反之,返回false

s1.addAll(s2) — 将s1和s2的并集存入s1

s1.retainAll(s2) — 将s1和s2的交集存入s1

s1.removeAll(s2) — 移除s1中与s2重合的元素

Java平台提供了三种通用实现类:HashSet,TreeSet和LinkedHashSet。

HashSet用哈希表作为容器,是性能最好的实现类,但是它不保证迭代顺序,元素的顺序不是固定的

TreeSet用红黑树作为容器,根据元素值进行排序,它的效率要比HashSet低很多

LinkedHashSet也是用哈希表实现的,不同的是,哈希表中运行着一个链表,元素按照插入的先后顺序排序。LinkedHashSet的元素顺序比混乱的HashSet要清晰很多,但是效率要比HashSet低

HashSet

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

此类为基本操作提供了稳定性能,这些基本操作包括 add、remove、contains 和 size,假定哈希函数将这些元素正确地分布在桶中。对此 set 进行迭代所需的时间与 HashSet 实例的大小(元素的数量)和底层 HashMap 实例(桶的数量)的“容量”的和成比例。因此,如果迭代性能很重要,则不要将初始容量设置得太高(或将加载因子设置得太低)。

HashSet除了集合的通用实现类都有的无参构造函数和接受一个Collection作为参数的构造函数,还有两个特殊的构造函数:

HashSet(intinitialCapacity)

构造一个新的空 set,其底层 HashMap 实例具有指定的初始容量和默认的加载因子(0.75)。

HashSet(intinitialCapacity, float loadFactor)

构造一个新的空 set,其底层 HashMap 实例具有指定的初始容量和指定的加载因子。

初始容量的默认值为16,加载因子的默认值为0.75

需要注意的是,HashSet不支持Collection接口中定义的批量操作方法,如addAll()、containsAll()、removeAll()、retainAll()

TreeSet

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

注意,如果要正确实现 Set 接口,则 set 维护的顺序(无论是否提供了显式比较器)必须与 equals 一致。这是因为 Set 接口是按照 equals 操作定义的,但 TreeSet 实例使用它的 compareTo(或 compare)方法对所有元素进行比较,因此从 set 的观点来看,此方法认为相等的两个元素就是相等的。即使 set 的顺序与 equals 不一致,其行为也是定义良好的;它只是违背了 Set 接口的常规协定。

该实现类也有两个特殊的构造方法:

TreeSet(Comparator<?super E> comparator)

构造一个新的空 TreeSet,它根据指定比较器进行排序。

TreeSet(SortedSet<E>s)

构造一个与指定有序 set 具有相同映射关系和相同排序的新 TreeSet。

TreeSet扩展方法(即没有在Set接口中定义的方法):

E ceiling(E e)

返回此 set 中大于等于给定元素的最小元素;如果不存在这样的元素,则返回 null。

Comparator<?super E> comparator()

返回对此 set 中的元素进行排序的比较器;如果此 set 使用其元素的自然顺序,则返回 null。

NavigableSet<E> descendingSet()

返回此 set 中所包含元素的逆序视图。

E first()

返回此 set 中当前第一个(最低)元素。

E floor(E e)

返回此 set 中小于等于给定元素的最大元素;如果不存在这样的元素,则返回 null。

SortedSet<E> headSet(E toElement)

返回此 set 的部分视图,其元素严格小于toElement。

NavigableSet<E> headSet(E toElement,boolean inclusive)

返回此 set 的部分视图,其元素小于(或等于,如果 inclusive 为 true)toElement。

E higher(E e)

返回此 set 中严格大于给定元素的最小元素;如果不存在这样的元素,则返回 null。

E last()

返回此 set 中当前最后一个(最高)元素。

E lower(E e)

返回此 set 中严格小于给定元素的最大元素;如果不存在这样的元素,则返回 null。

E pollFirst()

获取并移除第一个(最低)元素;如果此set 为空,则返回 null。

E pollLast()

获取并移除最后一个(最高)元素;如果此set 为空,则返回 null。

NavigableSet<E> subSet(E fromElement,boolean fromInclusive, E toElement, boolean toInclusive)

返回此 set 的部分视图,其元素范围从fromElement 到 toElement。

SortedSet<E> subSet(E fromElement, EtoElement)

返回此 set 的部分视图,其元素从fromElement(包括)到 toElement(不包括)。

SortedSet<E> tailSet(E fromElement)

返回此 set 的部分视图,其元素大于等于fromElement。

NavigableSet<E> tailSet(E fromElement,boolean inclusive)

返回此 set 的部分视图,其元素大于(或等于,如果 inclusive 为 true)fromElement。

需要注意的是TreeSet实现了SortedSet接口,实现了该接口的子类中,视图操作(即subSet、tailSet等方法)与List有很大不同。List的视图操作在源列表修改后将会抛出异常,比如,我们截取一个使用subList方法截取List的一段元素作为操作对象,一旦源List进行了插入、删除等操作,则用subList获取的子列表将会抛出异常。而SortedSet的子类不会出现这种情况,因为使用subSet截取SortedSet的起始点是不是固定的某两个元素,而是其下标的绝对位置,对源集合的修改会同步到子集合当中,反之亦然。另外,Set的视图操作与List一样,是半开放的,即包含低位段,不包含高位段,比如,有一个Set包含的元素为字母a-g,subSet(‘a’,’d’)得到的结果是包含’a’、’b’、’c’的集合

LinkedHashSet

具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现。此实现与 HashSet 的不同之外在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,即按照将元素插入到 set 中的顺序(插入顺序)进行迭代。注意,插入顺序不受在set 中重新插入的元素的影响。(如果在 s.contains(e) 返回 true 后立即调用 s.add(e),则元素 e 会被重新插入到 set s 中。)

此实现可以让客户免遭未指定的、由HashSet 提供的通常杂乱无章的排序工作,而又不致引起与 TreeSet 关联的成本增加。使用它可以生成一个与原来顺序相同的 set 副本,并且与原 set 的实现无关:

     void foo(Set s) {
         Set copy = new LinkedHashSet(s);
         ...
     }

如果模块通过输入得到一个 set,复制这个 set,然后返回由此副本决定了顺序的结果,这种情况下这项技术特别有用。(客户通常期望内容返回的顺序与它们出现的顺序相同。)

扩展的构造方法:

LinkedHashSet(intinitialCapacity)

构造一个带指定初始容量和默认加载因子(0.75) 的新空链接哈希 set。

LinkedHashSet(intinitialCapacity, float loadFactor)

构造一个带有指定初始容量和加载因子的新空链接哈希 set。

该实现类没有扩展的方法,与Set接口中定义的方法一致

时间: 2024-08-04 16:57:49

集合框架1.2之Set接口的相关文章

Java—集合框架 Collections.sort()、Comparable接口和Comparator接口

Collentions工具类--java.util.Collections Collentions是Java集合框架中,用来操作集合对象的工具类,也是Java集合框架的成员,与List.Map和Set是并列的. Collections.sort() 排序方法,实现对List对象中的元素进行排序. package com.test.collection; import java.util.ArrayList; import java.util.Collections; import java.ut

Java学习关于集合框架的基础接口--Collection接口

 集合框架(Collection  Framework)是Java最强大的子系统之一,位于java.util 包中.集合框架是一个复杂的接口与和类层次,提供了管理对象组的最新技术.Java集合框架标准化了程序处理对象组的方式. 集合框架在设计上需要满足几个目标.首先,框架必须是高性能的.基本集合(动态数组.链表.树以及哈希表)的实现是高效率的.很少需要手动编写这些数据引擎中的某一个.其次,框架必须允许不同类型的集合以类似的方式进行工作,并且具有高度的互操作性.再次,扩展或改造必须易于实现.为了满

我所理解Java集合框架的部分的使用(Collection和Map)

所谓集合,就是和数组类似--一组数据.java中提供了一些处理集合数据的类和接口,以供我们使用. 由于数组的长度固定,处理不定数量的数据比较麻烦,于是就有了集合. 以下是java集合框架(短虚线表示接口,长虚线表示抽象类,实线表示类,箭头表示实现接口或者继承)(在网络上找的图,不知道原作者,侵权请联系我删除)(总之,关系很复杂,所以不用记得这个图,只是用来吓吓人而已的). 下面贴上个人理解之精简版之Collection(集)和Map(地图?暂且这么理解吧),话说思维导图蛮好用,以下是两幅思维导图

2016.3.9-3.10(java集合框架)

3.9 集合框架有什么作用? 集合框架其主要功能是用来将存储的数据以某种结构组织,并以特定的方式来访问这些数据. Java集合框架中有哪些存储方式? Java集合框架中的对象容器,按照对象在其中的存储方式,分为Set.List.和Map三种类型. Set类型对象没有顺序,且不能重复: List类型对象容器中的对象按照索引顺序排序,而且可以有重复的对象: Map类型对象容器中的元素包含一对“键对象-值对象”映射,其中键对象不能重复,值对象可以重复. 以上三种存储方式对应Java集合框架中Set.L

Java 集合框架

Java 集合框架 早在Java 2中之前,Java就提供了特设类.比如:Dictionary, Vector, Stack, 和Properties这些类用来存储和操作对象组. 虽然这些类都非常有用,但是它们缺少一个核心的,统一的主题.由于这个原因,使用Vector类的方式和使用Properties类的方式有着很大不同. 集合框架被设计成要满足以下几个目标. 该框架必须是高性能的.基本集合(动态数组,链表,树,哈希表)的实现也必须是高效的. 该框架允许不同类型的集合,以类似的方式工作,具有高度

集合框架-Map

 Map集合 * 1.Map集合中存储的是一对儿元素.键和值.之间存在着对应关系. * 2.必须要保证键的唯一性. * 3.如果存储键相同,值会覆盖. 集合框架-Map-常见方法 put(K key, V value)     将指定的值与此映射中的指定键关联(可选操作). 返回: 返回与 key 相关联的先前值,如果 key 没有映射关系,则返回 null(返回 null 可能还表示映射以前将 null 与指定键关联) get(Object key) 返回: 指定键所映射的值:如果此映射不包含

黑马程序员——JAVA集合框架学习总结

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- www.itheima.com 要学好java的集合框架,必须掌握此图: Java集合框架很全面,从大的来说.它包括两种类型: 1.一种是以collection为根接口的集合. 2.另一种是由map为根接口的<key,value>的“图”. 而collection之下的set接口和list接口又有不同: 1.Set 接口继承 Collection,但不允许重复,使用自己内部的一个排列机制.

集合框架图

简化图: Java平台提供了一个全新的集合框架."集合框架"主要由一组用来操作对象的接口组成.不同接口描述一组不同数据类型. Java 2集合框架图集合接口:6个接口(短虚线表示),表示不同集合类型,是集合框架的基础.抽象类:5个抽象类(长虚线表示),对集合接口的部分实现.可扩展为自定义集合类.实现类:8个实现类(实线表示),对接口的具体实现.在很大程度上,一旦您理解了接口,您就理解了框架.虽然您总要创建接口特定的实现,但访问实际集合的方法应该限制在接口方法的使用上:因此,允许您更改基

Java基础---泛型、集合框架工具类:collections和Arrays

第一讲     泛型(Generic) 一.概述 1.JDK1.5版本以后出现的新特性.用于解决安全问题,是一个类型安全机制. 2.JDK1.5的集合类希望在定义集合时,明确表明你要向集合中装入那种类型的数据,无法加入指定类型以外的数据. 3.泛型是提供给javac编译器使用的可以限定集合中的输入类型说明的集合时,会去掉“类型”信息,使程序运行效率不受影响,对参数化的泛型类型,getClass()方法的返回值和原始类型完全一样. 4.由于编译生成的字节码会去掉泛型的类型信息,只要能跳过编译器,就