【Java语法栏——Java集合三】Set接口

5 篇文章 1 订阅

一 Set集合概念

1 Set集合概念

在 Java 中,Set 是集合框架中的一种接口,它表示不允许包含重复元素的集合。Set 接口继承自 Collection 接口,它没有提供额外的方法,但是它保证了集合中不会包含相同的元素。Set 接口的主要实现类有 HashSetLinkedHashSetTreeSet 等。


2 Set集合特点
  • 无序Set 不保证元素的顺序,即元素不按照特定的顺序存储和访问。
  • 不可重复:不允许包含重复的元素。如果试图向 Set 中添加已经存在的元素,add 方法将返回 false
  • 无索引:没有带索引的方法,所以不能使用普通for循环遍历,也不能通过索引来获取元素。

3 Set集合的实现类
  • HashSet:底层是哈希表,线程不安全的,无序,不重复,无索引(使用场景:对集合中的元素去重)
  • LinkedHashSet:底层是链表+哈希表,线程不安全的,有序,不重复,无索引(使用场景:对集合中的元素去重,而且保证存取顺序)
  • TreeSet:底层是二叉树,线程不安全的,可排序,不重复,无索引(使用场景:对集合中的元素进行排序)

二 实现方式

采用多态的形式

Set<String> set=new HashSet<>();
Set<String> set=new LinkedHashSet<>();
Set<String> set=new TreeSet<>();

三 常用方法

和Collection接口的方法大概一致,以下列举部分

boolean add(E e)添加指定元素
boolean remove(Object o)移除指定元素
boolean contains(Object o)判断集合中是否存在指定的元素
int size()返回集合中元素的个数
boolean isEmpty()判断当前集合是否为空
void clear()清空集合中的元素

四 Set的实现类HashSet

1 HashSet底层原理

HashSet集合底层采取哈希表存储数据

注:哈希表是一种对于增删改查数据性能都较好的结构。

哈希表的组成:

  • JDK8之前:数组+链表

  • JDK8之后:数组+链表+红黑树

存储规则:

  1. 创建一个默认长度为16,默认加载因子为0.75的数组,数组名为table
  2. 根据元素的哈希值与数组长度计算出应存入的位置
  3. 判断当前位置是否为null,如果是null则存入
  4. 如果位置不为null,表示有元素,则调用equals方法比较属性值
  5. 比较结果如果一致:不存储;比较结果不一致,形成链表
  • JDK8之前:新元素存入数组,老元素挂在新元素下面
  • JDK8之后:新元素直接挂在老元素下面。当链表长度超过8,而且数组长度大于等于64时,自动转换为红黑树;如果集合存储的是自定义对象,必须要重写hashCode和equals方法(因为如果不重写,比较的就是对象的地址值,为false)。 

五 Set的实现类LinkedHashSet

1 LinkedHashSet底层原理

HashSet集合底层采取哈希表存储数据,每个元素额外的多了一个双链表的机制记录存储的顺序


六 Set的实现类TreeSet

1 TreeSet底层原理

HashSet集合底层采取红黑树存储数据


2 TreeSet排序规则

方式一:默认排序/自然排序

(1)默认排序

  • 对于数值类型:Integer,Double,默认按照从小到大的顺序进行排序
  • 对于字符、字符串类型,按照字符在ASCII码表中的数字升序进行排序

测试数字的排序

/**
 * 测试数字的排序
 */
public class TreeSetDemo {
    public static void main(String[] args) {
        Set<Integer> set=new TreeSet<>();
        set.add(1);
        set.add(9);
        set.add(2);
        set.add(6);
        System.out.println(set);
    }
}

测试字符串的排序

/**
 * 测试字符串的排序
 */
public class TreeSetDemo {
    public static void main(String[] args) {
        Set<String> set=new TreeSet<>();
        set.add("ab");
        set.add("ac");
        set.add("aba");
        set.add("c");
        set.add("cdb");
        set.add("bdddd");
        System.out.println(set);
    }
}

(2)JavaBean类实现Comparable接口指定比较规则

public class Teacher implements Comparable<Teacher>{
    private String name;
    private int age;

    public Teacher(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    public int getAge() {
        return age;
    }

    @Override
    public String toString() {
        return "Teacher{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public int compareTo(Teacher o) {
        System.out.println("this:"+this+",o:"+o);
        System.out.println("---------------------------");
        return this.getAge()-o.getAge();
    }
}

此处就重写了一个方法compareTo

o:红黑树中的元素

this:即将要插入的元素

return:

  • 0:当前要添加的元素已存在,不添加
  • 负数:当前要添加的元素是小的,添加到红黑树的左子树
  • 正数:当前要添加的元素是大的,添加到红黑树的右子树
import java.util.Set;
import java.util.TreeSet;

public class TreeSetComparable {
    public static void main(String[] args) {
        Teacher t1 = new Teacher("张三", 23);
        Teacher t2 = new Teacher("李四", 24);
        Teacher t3 = new Teacher("王五", 20);
        Teacher t4 = new Teacher("赵六", 24);

        Set<Teacher> set = new TreeSet<>();
        set.add(t1);
        set.add(t2);
        set.add(t3);
        set.add(t4);

        System.out.println(set);

    }
}

默认使用第一种,如果第一种不能满足当前需求,就使用第二种

方式二:比较器排序

import java.util.Comparator;
import java.util.TreeSet;

public class TreeSetComparator {
    public static void main(String[] args) {
        TreeSet<String> set=new TreeSet<>(new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                //按照长度排序
                int i=o1.length()-o2.length();
                //如果长度一致则按照首字母排序
                i=i==0?o1.compareTo(o2):i;
                return i;
            }
        });
        set.add("hello");
        set.add("helle");
        set.add("holle");
        set.add("to");
        set.add("java");
        System.out.println(set);
    }
}

注:返回值和上述方式1一致,此处的compareTo是String的方法。

  • 43
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值