活动地址: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;
}
提醒:在发布作品前请把不用的内容删掉(活动地址请保留)