Set接口的实现类

1.简述

  Set接口和List接口一样,同样继承自Collection接口,它与Collection接口中的方法基本一致,并没有对Collection接口进行功能上的扩充,只是比Collection接口更加严格了。与List接口不同的是,Set接口中元素无序,并且都会以某种规则保证存入的元素不出现重复。

  特点

  • 存入顺序和取出顺序不一致,不保证顺序不变,且元素唯一,底层由HashMap实现。

  Set接口中有以下几个常用实现类

  • HashSet:无序并且性能比TreeSet高效,适用于基本的添加、查询元素的场合。
  • TreeSet:采用的二叉树的数据结构,需要采用红黑树算法维护数据的排序,对Set的数据类型有要求(需要实现Comparable接口或者是在TreeSet构造的时候定义排序),性能较HashSet低效,比较适用于需要保持排序的场景。
  • LinkedHashSet:采用的链表维护插入元素的顺序,其他与HashSet无太大差异,性能较HashSet略低(链表开销)。
  • EnumSet:这四种常见Set实现类中最高效的,采用的是位向量的数据结构存储元素(存储高效、紧凑),要求存储元素必须是一个Enum(约束大),适用于枚举值执行批量操作的场景。

2.HashSet

  该类实现了Set接口,不允许出现重复元素,不保证集合中元素的顺序,允许包含值为null的元素,但最多只能一个。对于HashSet而言,HashSet继承自AbstractSet,它是基于HashMap实现的,HashSet底层使用HashMap来保存所有元素。因此HashSet的实现比较简单,相关HashSet的操作,基本上都是直接调用底层HashMap 的相关方法来完成。

  定义一个HashSet的方式有如下几种

//构造一个新的空 set,其底层 HashMap 实例的默认初始容量是 16,加载因子是 0.75。
Set<String> set = new HashSet<String>();
//构造一个包含指定 collection 中的元素的新 set。
set = new HashSet<String>(new ArrayList<String>());
//构造一个新的空 set,其底层 HashMap 实例具有指定的初始容量和默认的加载因子(0.75)。
set = new HashSet<String>(30);
//构造一个新的空 set,其底层 HashMap 实例具有指定的初始容量和指定的加载因子。
set = new HashSet<String>(30, 1.2f);
View Code

  HashSet有很多常用方法,add、addAll、remove、clear、size、isEmpty等,关于其他方法可以查看API。

  HashSet的遍历方式和ArrayList一样,这里就不在陈述了。

3.TreeSet

  TreeSet是一个有序的集合,它的作用是提供有序的Set集合。它继承了AbstractSet抽象类,实现了NavigableSet<E>,Cloneable,Serializable接口。TreeSet是基于TreeMap实现的,TreeSet的元素支持2种排序方式,自然排序或者根据提供的Comparator进行排序。

  定义一个TreeSet的方式有如下几种

//默认构造函数。使用该构造函数,TreeSet中的元素按照自然排序进行排列。
Set<String> set = new TreeSet<String>();
//创建的TreeSet包含collection
set = new TreeSet<String>(new ArrayList<String>());
//指定TreeSet的比较器
set = new TreeSet<String>(new Comparator<String>() {
    public int compare(String o1, String o2) {
        int num = o1.compareTo(o2);                    //比较内容为主要条件
        return num == 0 ? 1 : num;                    //保留重复
    }
});
//创建的TreeSet包含set
SortedSet<String> sortedTreeSet = new TreeSet<String>();
set = new TreeSet<String>(sortedTreeSet);
View Code

  TreeSet有很多常用方法,add、addAll、remove、clear、size、isEmpty等,关于其他方法可以查看API。

  TreeSet的遍历方式和ArrayList一样,这里就不在陈述了。

4.LinkedHashSet

  相对HashSet来说,LinkedHashSet存储结构是一个双向链表,因此它存储的元素是有序的。LinkedHashSet继承自HashSet,源码更少、更简单,唯一的区别是LinkedHashSet内部使用的是LinkHashMap。这样做的意义或者好处就是LinkedHashSet中的元素顺序是可以保证的,也就是说遍历序和插入序是一致的。

  定义一个LinkedHashSet的方式有如下几种

//默认构造函数
Set<String> set = new LinkedHashSet<String>();
//创建的LinkedHashSet包含容量初始化
set = new LinkedHashSet<String>(30);
//创建的LinkedHashSet包含容量和填充比初始化
set = new LinkedHashSet<String>(30, 12.5f);
//将其他类型的集合转为LinkedHashSet
set = new LinkedHashSet<String>(new ArrayList<String>());
View Code

  LinkedHashSet有很多常用方法,add、addAll、remove、clear、size、isEmpty等,关于其他方法可以查看API。

  LinkedHashSet的遍历方式和ArrayList一样,这里就不在陈述了。

5.EnumSet

  EnumSet是一个专为枚举设计的集合类,EnumSet中的所有元素都必须是指定枚举类型的枚举值,该枚举类型在创建EnumSet时显式或隐式地指定。EnumSet的集合元素是有序的,并且不允许加入null元素。EnumSet在内部以位向量的形式存储,这种存储形式非常紧凑、高效,因此EnumSet对象占用内存很小,而且运行效率很好。

  EnumSet是抽象类,只能通过静态工厂方法构造EnumSet对象,具体如下

  • EnumSet<E> noneOf(Class<E> elementType):构造一个空的集合
  • EnumSet<E> allOf(Class<E> elementType):构造一个包含枚举类中所有枚举项的集合
  • EnumSet<E> of(E e):构造包含1个元素的集合
  • EnumSet<E> of(E e1, E e2):构造包含2个元素的集合
  • EnumSet<E> of(E e1, E e2, E e3):构造包含3个元素的集合
  • EnumSet<E> of(E e1, E e2, E e3, E e4):构造包含4个元素的集合
  • EnumSet<E> of(E e1, E e2, E e3, E e4, E e5):构造包含5个元素的集合
  • EnumSet<E> of(E first, E... rest):构造包含多个元素的集合(使用可变参数)
  • EnumSet<E> copyOf(EnumSet<E> s):构造包含参数中所有元素的集合
  • EnumSet<E> copyOf(Collection<E> c):构造包含参数中所有元素的集合

  EnumSet有很多常用方法,add、addAll、remove、clear、size、isEmpty等,关于其他方法可以查看API。

  EnumSet的遍历方式和ArrayList一样,这里就不在陈述了。

posted on 2020-10-26 16:38  码农记录  阅读(889)  评论(0编辑  收藏  举报

导航