Java的Set集合


活动地址:CSDN21天学习挑战赛

一.Set集合

1.1特点

1.三种实现类特点

 HashSet: 	无序(存取顺序不同),不重复,无索引
 LinkedHashSet:有序,不重复,无索引
 TreeSet:排序,不重复(可以去除重复),无索引(不能使用普通for循环遍历)

2.API
Set集合功能基本和Collection的API一致

1.2底层原理
1.1.1HashSet集合元素无序的底层原理

采取哈希表存储数据,有利于增删改查。
(1)哈希表:

 JDK8之前,由数组+链表组成
 JDK8之后,由数组+链表+红黑树组成

(2)哈希值:

 是JDK根据对象地址,按照某种规则计算得到的int类型数值
 对象哈希值:
        同一个对象多次调用hashCode()方法返回的哈希值相同
        默认情况下,不同对象哈希值不同。
   Object类API:public int hashCode():返回对象的哈希值

(3)HashSet 原理图
请添加图片描述
1.7版本原理解析:

  (1)创建一个默认长度16的数组,数组名table
  (2)根据元素的哈希值跟数组的长度求余计算出应存入的位置(哈希算法)
  (3)判断当前位置是否为空- null,如果为空直接存入
  (4)如果该位置不为空,表示有元素,则调用equals方法比较
  (5)如果一样,则不存,当不一样时,存入数组
  (6)当数组存满16*0.75=12时,自动扩容为原来的两倍
  注释:JDK7新元素占老元素位置,指向老元素
             JDK8新元素挂在老元素下面

1.8版本原理解析
底层结构:由数组+链表+红黑树组成的哈希表
注释:

   当挂在元素下面的元素过多时,查询性能降低,
   JDK8以后,当链表长度8时,自动转为红黑树

请添加图片描述
请添加图片描述

1.1.2HashSet集合元素去重复的底层原理
  (1) 创建一个默认长度16的数组,数组名table
  (2)重写hashCode()和equals()方法,用于内容相同对象的去重
  (3)根据元素的哈希值跟数组的长度求余计算出应存入的位置(哈希算法)
  (4)判断当前位置是否为空- null,如果为空直接存入
  (5)如果该位置不为空,表示有元素,则调用equals方法比较
  (6)如果一样,则不存,当不一样时,存入数组
  (7)当数组存满16*0.75=12时,自动扩容为原来的两倍

案例:
创建一个存储学生对象的集合,存储多个学生对象,使用程序实现在控制台遍历该集合,要求:学生对象的成员变量值相同,我们就认为是同一个对象

import  java.util.*;
public class Main
{
    public static void main(String[] args){
        Set hs=new HashSet();
        hs.add(new Student("1","张三"));
        hs.add(new Student("2","张三"));
        hs.add(new Student("3","李四"));
        for(Object stu:hs)
            System.out.println(stu);
    }
}
class Student{
    private String id;
    private String name;
    Student(String id,String name){
    this.id=id;
    this.name=name;
}
    @Override
    public String toString(){
        return id+':'+name;
    }
    @Override
    public int hashCode(){
        return id.hashCode();
    }
    @Override
    public boolean equals(Object obj){
        if(this==obj)
            return true;
        if(!(obj instanceof Student))
            return false;
        Student stu=(Student) obj;
        boolean b=this.id.equals(stu.id);
        return b;
    }

}
1.2.1LinkedHashSet集合的底层原理

底层基于哈希表,使用双链表记录添加顺序

请添加图片描述

1.3.1TreeSet集合的底层原理

底层基于红黑树实现排序(默认或指定),增删改查性能较好
默认排序规则:

  对于数值类型:Integer,Double ,默认按照大小进行升序排序
  对于字符类型:默认按照首字母的编号升序排序
  对于自定义类型如Student对象,TreeSet无法直接排序,需要自定义排序
  TreeSet集合存储的对象有实现比较规则,集合也自带比较器,默认使用集合自带的比较器排序。

自定义排序:

 方式一:
    自定义类(如学生类)实现Comparable接口重写compare To方法定义排序
 方式二:
     TreeSet集合有参构造器,可设置Comparator接口对应的比较器,定义排序

自定义排序的返回值:

  若第一个元素大于第二个元素返回正整数
  若第一个元素等于第二个元素返回0,判定为重复,只保留其中之一
  若第一个元素小于第二个元素返回负整数

案例:
键盘录入3个学生信息(姓名,语文成绩,数学成绩,英语成绩),按照总分从高到低输出到控制台

import  java.util.*;
public class Main
{
    public static void main(String[] args){
        Set hs=new TreeSet();
        hs.add(new Student(100,90,80,"张三"));
        hs.add(new Student(100,70,80,"张三"));
        hs.add(new Student(100,60,80,"李四"));
        for(Object stu:hs)
            System.out.println(stu);
    }
}
class Student  implements Comparable{ //注意接口写入
    private int s1;
    private int s2;
    private int s3;
    private String name;
    Student(int s1,int s2,int s3,String name){
        this.s1=s1;
        this.s2=s2;
        this.s3=s3;
        this.name=name;
    }
    @Override
    public String toString(){

        return name+':'+this.get();
    }
    public int get()
    {
        return this.s1+this.s2+this.s3;
    }
 @Override
    public int compareTo(Object obj){
        Student stu=(Student) obj;
        if(this.get()-stu.get()>0)
            return 1;
        if(this.get()-stu.get()==0)
            return this.name.compareTo(stu.name);
        return -1;

    }



提醒:在发布作品前请把不用的内容删掉(活动地址请保留)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梅花与竹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值