Java基础——常用对象API(4):集合框架3:Set集合

在这里插入图片描述

1.Set系列集合特点

1.1 与List比较

List:有序,可重复,有索引
Set:无序,不重复,无索引

1.2 HashSet

添加的元素无序,不重复,无索引。内部数据结构是哈希表,是不同步的。

1.3 LinkedHashSet

添加的元素,有序,不重复,无索引。

1.4 TreeSet

按照大小默认升序排序,不重复,无索引。

关于排序:

  1. 字符串按照首字符排序。首字符相同时,看第二位,依此类推。

  2. 有值特性的元素(int,float等),按照数值大小排序。

  3. 自定义的引用类型,可以:
    --------- 在对象类中重写Comparable接口的compareTo()方法。
    --------- 为集合设置比较器对象,即重写Comparator接口的Compare()方法。

如果两样都被实现,优先使用比较器的比较规则。

ps: 具体代码实现,详见3.2.2
在这里插入图片描述


2.Set集合的两个问题

2.1 Set集合添加的元素如何去重合?

  • 对于有值特性(String,Integer,int)的,直接判断进行去重复。
  • 对于引用数据类型的类对象:
  1. hashCode
  2. equals

首先Set集合会让两两对象,先调用自己的hashCode()方法,判断两个对象的哈希值是否相同;如果相同,再用equals()方法判断内容是否相同。

如果哈希值不同,则无需判断内容是否相同。

2.2 Set集合无序的原因

Set集合添加元素无序是因为其底层用哈希表存储元素:

JDK1.8之前,哈希表 = 数组 + 链表 + (哈希算法)

JDK1.8之后,哈希表 = 数组 + 链表 + 红黑树 +(哈希算法)

哈希算法:

  1. 先获取元素对象的哈希值
  2. 用哈希值对底层数组的长度取余
  3. 取余的结果作为该元素在底层数组的索引位置
  4. 存入该元素对象
    ps:如果索引位置相同,在该数组的位置形成链,依次连接。
    在这里插入图片描述

用哈希表存储元素,增删改查性能好,但它无序,不重复。
同时考虑到链表可能过长影响性能,在JDK1.8之后,当链表长度超过8时,链表会 转成红黑树

ps:LinkedHashSet在底层依然是用哈希表存储元素,

但是每个元素额外带一个链维护添加顺序,顺着这条链,有序查找输出元素。


3. 代码示例

3.1 用HashSet存储自定义对象

规定:如果学生类的姓名和年龄一样,则视为同一个对象。

分析:即使Student对象内的姓名和年龄完全相同,因为哈希值是根据对象地址得出的,所以把数值完全相同的对象往HashSet集合存储时,都会被存进去。但是现在规定姓名和年龄一样,则视为同一个对象,也就是存进去时前一个要被去掉。‘

所以
通过重写hashCode()方法和equals()方法可实现规定内容。

做法:重写方法时,让哈希值根据name和age得出;如果哈希值相同,重写后的equals方法判断name和age的值是否相同,若相同,则该对象不会进入HashSet。

import java.util.HashSet;
import java.util.Iterator;

class Student {
   
    private String name;
    private int age;

    Student() {
   

    }

    Student(String name, int age) {
   
        this.name = name;
        this.age = age;
    }

    @Override
    public int hashCode() {
   
        return name.hashCode()+age;
    }

    @Override
    public boolean equals(Object obj) {
   
        Student s = (Student)obj;
        return this.name.equals(s.name) && this.age==s.age;
    }

    public int getAge() {
   
        return age;
    }

    public String getName() {
   
        return name;
    }
}

public class HashCodeDemo {
   
    public static void main(String[] args) {
   
        HashSet hashSet = new HashSet();

        hashSet.add(new Student("abc1",21));
        hashSet.add(new Student("abc2",22));
        hashSet
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值