集合框架之Set集合

简介: 集合框架之Set集合

前言

1.为什么要使用Set集合?

1.1.去重

Set集合中的元素是不重复的,如果我们需要去除一个列表或元组中的重复元素,就可以转换为set类型来达到去重的目的。

1.2.提高查找速度

由于Set集合是通过哈希表实现的,所以查找元素的时间复杂度为O(1),相对于列表或元组来说,它的查找速度更快。

1.3.数学运算

集合论是计算机科学中的重要分支,Set集合可以用于实现集合论中的各种运算,如并集、交集、差集等。

2.使用场景

     在公司内有可能要用别人的接口,而别人对于传过来的数据可能是有重复或者杂乱无章的,因为不是我们的数据库不能进行sql语句的编辑,达到自己想要的效果,那么就可以用到set集合,从而达到我们的去重复和排序的需求。

 

一、Set集合

Set特点

1.1无序:元素输入的顺序与插入的顺序不一致。

Set<Integer> set=new HashSet<Integer>();
set.add(3);
set.add(0);
set.add(2);
set.add(3);
System.out.println(set);

1.2元素唯一:不允许添加重复的元素。

1.3无下标

Set<Integer> set=new HashSet<Integer>();
set.add(2);
set.add(0);
set.add(2);
set.add(3);
set.add(6);
System.out.println(set);

由于Set集合中的数据是唯一的,那么Set集合是怎么让它里面的元素不重复呢?

  • 判断重复元素的时候,Set集合会调用hashCode()equal()方法来实现;而在没有重写equals方法之前默认比较的是Object(引用类型),实际上比较的是内存地址。
  • 【先比较hashcode值是否相同,再比较equals】
  • 比较对象的属性相同时,已存在的对象信息不会被覆盖,而是过滤了

 如果添加重复元素是覆盖?还是过滤?怎么实现去除重复的?

实战操作:

//Set存储字符串可以去重,那么存储对象呢?           
    HashSet<stu> s=new HashSet<stu>();
    s.add(new stu(1, "aa"));
    s.add(new stu(2, "bb"));
    //是否包含
    boolean contains = s.contains(new stu(1, "aa"));
    System.out.println(contains);
      // 这里打印结果是false,不包含。
  }
}

  这里发现同样的名字居然可以重复存储,那这不是违背了Set的特点吗?其实不然,因为对象是new出来的,在内存上开辟了一个新的内存地址,如果不重写equals方法和hashCode方法默认比较的就是内存地址;

⚠注意:如果只重写equals方法,默认还是比较内存地址,需要equals方法和hashCode方法一起重写,才能达到去除重的效果,当我hashCode一致时候,会进行equals比较。如果equals返回的是true,那说明一致,则不会添加,也就是过滤掉了。

三、Set集合的子类

1.HashSet

       HashSet特点

  • 无序性:HashSet中的元素是无序的,即元素在HashSet中的位置和插入的顺序无关。
  • 唯一性:HashSet中的元素是唯一的,即同一个元素在HashSet中只会存储一次。
  • 基于哈希表实现:HashSet是基于哈希表实现的,这就意味着HashSet中的元素必须实现hashCode()和equals()方法,以便进行快速查找。
  • 元素可以为null:HashSet可以存储null元素,但只能存储一个null元素。
  • 非线程安全:HashSet是非线程安全的,如果多个线程同时修改同一个HashSet,就会出现并发问题。

2.LinkedHashSet

        LinkedHashSet特点

  • 有序性:LinkedHashSet中的元素是有序的,即元素在LinkedHashSet中的位置与插入的顺序相同
  • 唯一性:LinkedHashSet中的元素是唯一的,即同一个元素在LinkedHashSet中只会存储一次
  • 基于哈希表+链表实现:LinkedHashSet同时保留了哈希表的高效性和链表的有序性,使用哈希表来实现元素的查找,使用链表来维护元素的插入顺序。
  • 元素可以为null:LinkedHashSet可以存储null元素,但只能存储一个null元素。
  • 非线程安全:LinkedHashSet是非线程安全的,如果多个线程同时修改同一个LinkedHashSet,就会出现并发问题。

3.TreeSet

 TreeSet 是一个有序的集合,它的作用是提供有序的Set集合。TreeSet是基于TreeMap实现的。TreeSet中的元素支持2种排序方式:自然排序 或者 根据创建TreeSet 时提供的 Comparator 进行排序。

自然排序:排序的实体类实现java.lang.Comparable接口

HashSet<stus> s = new HashSet<>();
    s.add(new stus(1, "aa", 100));
    s.add(new stus(2, "bb", 101));
    s.add(new stus(3, "cc", 98));
    s.add(new stus(4, "dd", 34));
    s.add(new stus(5, "ee", 18));
     //定义一个treeset用于排序
     TreeSet<stus> tr=new TreeSet<>();
     for (stus stus : s) {
     tr.add(stus);//将数据加到集合
     }
     for (stus stus : tr) {
     System.out.println(stus);//输出结果
     }

⚠注意:一定要实现Comparable接口,否则会报

com.zking.set.xxx cannot be cast to java.lang.Comparable

并且重写compareTo方法

@Override
  public int compareTo(stus o) {
    return this.price - o.price;
  }

TreeSet构造器使用实现java.util.Comparator的匿名内部类

HashSet<stus> s = new HashSet<>();
    s.add(new stus(1, "aa", 18));
    s.add(new stus(2, "bb", 101));
    s.add(new stus(3, "cc", 98));
    s.add(new stus(4, "dd", 34));
    s.add(new stus(5, "ee", 18));
        /**
     * TreeSet构造器使用实现java.util.Comparator的匿名内部类
     * 
     * 如果价格一样根据编号升序
     */
    // 定义一个treeset用于排序
    TreeSet<stus> t = new TreeSet<>(new Comparator<stus>() {
      @Override
      public int compare(stus o1, stus o2) {
        /**如果价格一样再进行新一轮比较
         * 返回值:
         *  负数,表示当前对象比另一个对象小;
         *  零,表示当前对象和另一个对象相等; 
         *  正数,表示当前对象比另一个对象大。
         */
        if (o1.getPrice() - o2.getPrice() == 0) {
          return o1.compareTo(o2);
        }
        return o2.getPrice() - o1.getPrice();
      }
    });
    for (stus stus : s) {
      t.add(stus);// 将数据加到集合
    }
    for (stus stus : t) {
      System.out.println(stus);// 输出结果
    }

注意:Comparable是我和谁比,Comparator是谁和谁比。

直接return可能会出现精度丢失问题。个人建议使用if判断。

比较者大于被比较者返回正数

比较者等于被比较者返回零

比较者小于被比较者返回负数

本期介绍就到这.......😜😜😜😜😜😜😜

 

 

目录
相关文章
|
25天前
|
存储 NoSQL 关系型数据库
Redis 集合(Set)
10月更文挑战第17天
36 5
|
26天前
|
算法 Java 数据处理
从HashSet到TreeSet,Java集合框架中的Set接口及其实现类以其“不重复性”要求,彻底改变了处理唯一性数据的方式。
从HashSet到TreeSet,Java集合框架中的Set接口及其实现类以其“不重复性”要求,彻底改变了处理唯一性数据的方式。HashSet基于哈希表实现,提供高效的元素操作;TreeSet则通过红黑树实现元素的自然排序,适合需要有序访问的场景。本文通过示例代码详细介绍了两者的特性和应用场景。
36 6
|
26天前
|
存储 Java 数据处理
Java Set接口凭借其独特的“不重复”特性,在集合框架中占据重要地位
【10月更文挑战第16天】Java Set接口凭借其独特的“不重复”特性,在集合框架中占据重要地位。本文通过快速去重和高效查找两个案例,展示了Set如何简化数据处理流程,提升代码效率。使用HashSet可轻松实现数据去重,而contains方法则提供了快速查找的功能,彰显了Set在处理大量数据时的优势。
32 2
|
11天前
|
存储 Java
判断一个元素是否在 Java 中的 Set 集合中
【10月更文挑战第30天】使用`contains()`方法可以方便快捷地判断一个元素是否在Java中的`Set`集合中,但对于自定义对象,需要注意重写`equals()`方法以确保正确的判断结果,同时根据具体的性能需求选择合适的`Set`实现类。
|
11天前
|
存储 Java 开发者
在 Java 中,如何遍历一个 Set 集合?
【10月更文挑战第30天】开发者可以根据具体的需求和代码风格选择合适的遍历方式。增强for循环简洁直观,适用于大多数简单的遍历场景;迭代器则更加灵活,可在遍历过程中进行更多复杂的操作;而Lambda表达式和`forEach`方法则提供了一种更简洁的函数式编程风格的遍历方式。
|
11天前
|
Java 开发者
|
26天前
|
存储 Java 数据处理
Set 是 Java 集合框架中的一个接口,不包含重复元素且不保证元素顺序。
【10月更文挑战第16天】Java Set:无序之美,不重复之魅!Set 是 Java 集合框架中的一个接口,不包含重复元素且不保证元素顺序。通过 hashCode() 和 equals() 方法实现唯一性,适用于需要唯一性约束的数据处理。示例代码展示了如何使用 HashSet 添加和遍历元素,体现了 Set 的高效性和简洁性。
26 4
|
28天前
|
存储 Java 数据处理
Set 是 Java 集合框架中的一个接口,不包含重复元素且不保证元素顺序。
Java Set:无序之美,不重复之魅!Set 是 Java 集合框架中的一个接口,不包含重复元素且不保证元素顺序。它通过 hashCode() 和 equals() 方法确保元素唯一性,适用于需要唯一性约束的数据处理。示例代码展示了如何使用 HashSet 实现这一特性。
25 5
|
26天前
|
Java 开发者
在Java集合世界中,Set以其独特的特性脱颖而出,专门应对重复元素
在Java集合世界中,Set以其独特的特性脱颖而出,专门应对重复元素。通过哈希表和红黑树两种模式,Set能够高效地识别并拒绝重复元素的入侵,确保集合的纯净。无论是HashSet还是TreeSet,都能在不同的场景下发挥出色的表现,成为开发者手中的利器。
26 2
|
1月前
|
存储 JavaScript 前端开发
Set、Map、WeakSet 和 WeakMap 的区别
在 JavaScript 中,Set 和 Map 用于存储唯一值和键值对,支持多种操作方法,如添加、删除和检查元素。WeakSet 和 WeakMap 则存储弱引用的对象,有助于防止内存泄漏,适合特定场景使用。

热门文章

最新文章