百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

精解四大集合框架Set核心知识总结

toyiye 2024-06-21 12:09 9 浏览 0 评论

Set继承于Collection接口,是一个不允许出现重复元素,并且无序的集合,主要有HashSet和TreeSet两大实现类,另外LinkedHashSet也有一定的使用频率。

在判断重复元素的时候,Set集合会调用hashCode()和equal()方法来实现。

类图UML


Set常用方法

与List一样都是接口,Set接口也提供了集合操作的基本方法。Java四大集合之一,但与List不同的是,Set还提供了equals(Object o)和hashCode(),供其子类重写,以实现对集合中插入重复元素的处理;

 1public interface Set<E> extends Collection<E> {
 2    //添加
 3    boolean add(E e);
 4    boolean addAll(Collection<? extends E> c);
 5
 6    //删除
 7    boolean remove(Object o);
 8    boolean removeAll(Collection<?> c);
 9    void clear();
10
11    //长度
12    int size();
13    //是否为空
14    boolean isEmpty();
15
16    //是否包含
17    boolean contains(Object o);
18    boolean containsAll(Collection<?> c);
19    boolean retainAll(Collection<?> c); 
20
21    //获取Set集合的迭代器:
22    Iterator<E> iterator();
23
24    //把集合转换成数组
25    Object[] toArray();
26    <T> T[] toArray(T[] a);
27
28    //判断元素是否重复,为子类提高重写方法
29    boolean equals(Object o);
30    int hashCode();
31}

接口里知识定义了方法,具体的实现请看下面两个常用实现类。

HashSet

HashSet 是用来存储没有重复元素的集合类并且是无序的。实现了 Set 接口。底层其实主要是使用 HashMap 机制实现,所以也是线程不安全

部分源码:

1public class HashSet<E>  extends AbstractSet<E>  implements Set<E>, Cloneable, java.io.Serializable{
2    private transient HashMap<E,Object> map;
3    //这里这个PRESENT就是作为HashMap中的key
4    private static final Object PRESENT = new Object();
5    public HashSet() {
6        map = new HashMap<>();
7    }

特征:

  1. 不可重复
  2. 无序
  3. 线程不安全,若多个线程同时操作HashSet,必须通过代码实现同步;
  4. 集合元素可以是 null,但只能放入一个 null

使用场景:去重、不要求顺序

原理:HashSet底层由HashMap实现,插入的元素被当做是HashMap的key,根据hashCode值来确定集合中的位置,由于Set集合中并没有角标的概念,所以并没有像List一样提供get()方法。当获取HashSet中某个元素时,只能通过遍历集合的方式进行equals()比较来实现;

常用方法

 1    //添加
 2    public boolean add(E e) {
 3        return map.put(e, PRESENT)==null;
 4    }
 5    //移除
 6    public boolean remove(Object o) {
 7        return map.remove(o)==PRESENT;
 8    }
 9    //清空
10    public void clear() {
11        map.clear();
12    }
13    //获取迭代器
14    public Iterator<E> iterator() {
15        return map.keySet().iterator();
16    }
17    //判断是否为空
18    public boolean isEmpty() {
19        return map.isEmpty();
20    }
21    //求集合大小
22    public int size() {
23        return map.size();
24    }

正如上面所说,底层使用 HashMap 的 key 不能重复机制来实现没有重复的 HashSet。

TreeSet

TreeSet 实现了 SortedSet 接口,意味着可以排序,它是一个有序并且没有重复的集合类,底层是通过 TreeMap 实现。TreeSet 并不是根据插入的顺序来排序,而是字典自然排序。线程不安全。从名字上可以看出,此集合的实现和树结构有关。与HashSet集合类似,TreeSet也是基于Map来实现,具体实现TreeMap(后面讲解),其底层结构为红黑树(特殊的二叉查找树)。

TreeSet 支持两种排序方式:自然升序排序自定义排序

部分源码

 1public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>, Cloneable, java.io.Serializable{
 2
 3    private transient NavigableMap<E,Object> m;
 4
 5    private static final Object PRESENT = new Object();
 6
 7    TreeSet(NavigableMap<E,Object> m) {
 8        this.m = m;
 9    }
10
11    public TreeSet() {
12        this(new TreeMap<E,Object>());
13    }

常用方法

 1 //求集合大小
 2 public int size() {
 3     return m.size();
 4 }
 5 //判断是否为空
 6 public boolean isEmpty() {
 7     return m.isEmpty();
 8 }
 9 //判断是否包含
10 public boolean contains(Object o) {
11     return m.containsKey(o);
12 }

特征:

  1. 不可重复
  2. 有序,默认自然升序排序
  3. 线程不安全,若多个线程同时操作HashSet,必须通过代码实现同步;
  4. 集合元素不可以为 null
  5. 对插入的元素进行排序,是一个有序的集合(主要与HashSet的区别);
  6. 底层使用红黑树结构,而不是哈希表结构;

原理:

TreeSet 底层是基于 treeMap(红黑树结构)实现的,可以自定义比较器对元素进行排序,或是使用元素的自然顺序。

使用场景:去重、要求排序

LinkedHashSet

LinkedHashSet 是使用 HashSet 机制实现,它是一个可以保证插入顺序或是访问顺序,并且没有重复的集合类。线程不安全

数据结构:数组 + 双向链表,Entry 结构:before|hash|key|value|next|after,before 和 after 用于维护整个双向链表。

部分源码

 1public class LinkedHashSet<E> extends HashSet<E> implements Set<E>, Cloneable, java.io.Serializable {
 2
 3    public LinkedHashSet(int initialCapacity, float loadFactor) {
 4        super(initialCapacity, loadFactor, true);
 5    }
 6
 7    public LinkedHashSet(int initialCapacity) {
 8        super(initialCapacity, .75f, true);
 9    }
10
11    public LinkedHashSet() {
12        super(16, .75f, true);
13    }

常用方法

从这里可以看出,这家伙基本上都是使用HashSet来实现的,所以常用方法和HashSet相同。

特征:

  1. 集合元素不可以为 null;
  2. 线程不安全。

原理:

LinkedHashSet 底层使用了 LinkedHashMap 机制(比如 before 和 after),加上又继承了 HashSet,所以可以实现既可以保证迭代顺序,又可以达到不出现重复元素。

使用场景:去重、需要保证插入或者访问顺序

HashSet、TreeSet、LinkedHashSet 的区别

  • HashSet 只去重
  • TreeSet 去重并排序
  • LinkedHashSet 去重并保证迭代顺序。

推荐阅读

精解四大集合框架:List核心知识总结

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码