Java集合---04--Set

Set接口

在这里插入图片描述
**|----Collection接口:单列集合,用来存储一个一个的对象**

Set接口:

  • 存储无序的
  • 不可重复的数据

HashSet:

作为Set接口的主要实现类;

  • 线程不安全的

  • 可以存储null值

LinkedHashSet:

作为HashSet的子类;遍历其内部数据时,可以按照添加的顺序遍历 对于频繁的遍历操作,LinkedHashSet效率高于HashSet.

TreeSet:

可以按照添加对象的指定属性,进行排序。

Set:存储无序的、不可重复的数据

1.无序性:

  • 无序性:不等于随机性。存储的数据在底层数组中并非按照数组索引的顺序添加,而是根据数据的哈希值决定的。

2. 不可重复性:

保证添加的元素按照 equals() 判断时,不能返回true.即:相同的元素只能添加一个。

在这里插入图片描述

要求:

  1. 向Set(主要指:HashSet、LinkedHashSet)中添加的数据,其所在的类一定要重写hashCode()和equals()
  2. 要求:重写的hashCode()和equals()尽可能保持一致性:相等的对象必须具有相等的散列码

重写的hashCode()

在这里插入图片描述

重写的equals()

在这里插入图片描述

在这里插入图片描述

案例: User对象 重写hashCode()和equals()

在这里插入图片描述
实现 Comparable

public class User implements Comparable{
    private String name;
    private int age;

   

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

    @Override
    public boolean equals(Object o) {
        System.out.println("User equals()....");
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        User user = (User) o;

        if (age != user.age) return false;
        return name != null ? name.equals(user.name) : user.name == null;
    }

    @Override
    public int hashCode() { //return name.hashCode() + age;
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + age;
        return result;
    }
}

31最为系数,设置目的是减少哈希冲突.而且31是个素数且只占用5bit 造成数据溢出的概率很小

在这里插入图片描述

添加元素的过程:以HashSet为例:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

HashSet底层结构

数组+链表结构

数组初始容量为16 扩展因子0.75
在这里插入图片描述
HashSet 底层 有个 HashMap
在这里插入图片描述

LinkedHashSet

LinkedHashSet作为HashSet的子类,在添加数据的同时,每个数据还维护了两个引用,记录此数据前一个数据和后一个数据。

在这里插入图片描述

优点:

对于频繁的遍历操作,LinkedHashSet效率高于HashSet

TreeSet

概念:

  1. 向TreeSet中添加的数据,要求是相同类的对象
  2. 两种排序方式:自然排序(实现Comparable接口) 和 定制排序(Comparator)
  3. 自然排序中,比较两个对象是否相同的标准为:compareTo()返回0.不再是equals().
  4. 定制排序中,比较两个对象是否相同的标准为:compare()返回0.不再是equals().

在这里插入图片描述

结构:

在这里插入图片描述

自然排序:java.lang.Comparable

  • Comparable接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的 compareTo(T t)方法被称为它的自然比较方法。当前对象this与指定对象t比较“大小”,如果当前对象this大于指定对象t,则返回正整数,如果当前对象this小于指定对象t,则返回负整数,如果当前对象this等于指定对象t,则返回零。
  • 实现Comparable接口的对象列表(和数组)可以通过 Collections.sort(和 Arrays.sort)进行自动排序。实现此接口的对象可以用作有序映射中的键或有序集合中的元素,无需指定比较器。
  • 在这里插入图片描述

Comparable的典型实现:

  • String:按照字符串中字符的Unicode值进行比较
  • Character:按照字符的Unicode值来进行比较
  • 数值类型对应的包装类以及BigInteger、BigDecimal:按照它们对应的数值大小进行比较
  • Date、Time等:后面的日期时间比前面的日期时间大

定制排序:java.util.Compartor

  • 强行对某个对象 collection 进行整体排序 的比较函数。可以将 Comparator 传递给 sort 方法(如 Collections.sort 或 Arrays.sort),从而允许在排序顺序上实现精确控制。还可以使用 Comparator 来控制某些数据结构(如有序 set或有序映射)的顺序,或者为那些没有自然顺序的对象 collection 提供排序。
  • 当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码,或者实现了java.lang.Comparable接口的排序规则不适合当前的操作,那么可以考虑使用 Comparator 的对象来排序。

在这里插入图片描述

经典试题

在这里插入图片描述
在这里插入图片描述
其中Person 类 重写了 hashCode 和 equal()方法

public class Person {

     int id;
     String name;

    public Person(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public Person() {

    }

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

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Person person = (Person) o;

        if (id != person.id) return false;
        return name != null ? name.equals(person.name) : person.name == null;
    }

    @Override
    public int hashCode() {
        int result = id;
        result = 31 * result + (name != null ? name.hashCode() : 0);
        return result;
    }
}

开始

在这里插入图片描述
在这里插入图片描述

set.remove(p1);

在这里插入图片描述
在这里插入图片描述
解析:

  • person(1001.cc)是存在 开始 penson(1001 ,aa)哈希运算后的位置上的.所以remove操作,是根据person(1001.cc)哈希运算去删除,找不到相对应的元素.

set.add(new Person(1001,“CC”));

在这里插入图片描述
在这里插入图片描述
解析:

  • 第一个person(1001.cc)是存在 开始 penson(1001 ,aa)哈希运算后的位置上的.
  • 第二个person(1001.cc)是存在 本身 penson(1001 ,aa)哈希运算的位置上的.

在这里插入图片描述
最后结果 是四个值

  • Person(1001,“cc”)
  • Person(1002,“BB”)
  • Person(1001,“cc”)
  • Person(1001,“AA”)
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值