当前位置: 首页 > news >正文

JavaSe—Set集合

目录

1、认识Set集合的特点和常用操作

2、HashSet集合的底层原理

2.1 哈希值

2.2 哈希表

2.3 红黑树

3、HashSet集合元素的去重操作.

4、LinkedHashSet集合的底层原理

5、TreeSet集合

6、总结


1、认识Set集合的特点和常用操作

Set系列集合特点:无序:添加数据的顺序和获取出的数据顺序不一致;不重复、无索引;

  • HashSet:无序、不重复、无索引。
  • LinkedHashSet:无序、不重复、无索引。
  • TreeSet:排序、不重复、无索引。
  • 注意:Set要用的常用方法,基本上都是Collection提供的!!自己几乎没有额外新增一些常用功能!
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.TreeSet;public class SetDemo1 {public static void main(String[] args) {//// HashSet 无序,不可重复,无索引HashSet<String> set = new HashSet();   //一行经典代码set.add("hello");set.add("world");set.add("java");set.add("hello"); //添加重复元素set.add("55");System.out.println("无序,不可重复->: " + set);set.remove("55");System.out.println("删除55->: " + set);//LinkedHashSet//有序,不可重复,无索引LinkedHashSet<String> linkedHashSet = new LinkedHashSet();linkedHashSet.add("hello");linkedHashSet.add("world");linkedHashSet.add("java");linkedHashSet.add("hello");linkedHashSet.add("55");System.out.println("有序,不可重复->: " + linkedHashSet);//TreeSet////有序,不可重复,无索引TreeSet<String> treeSet = new TreeSet();treeSet.add("hello");treeSet.add("world");treeSet.add("java");treeSet.add("hello");treeSet.add("55");System.out.println("排序,不可重复->: " + treeSet);System.out.println("最小值->: " + treeSet.first());System.out.println("最大值->: " + treeSet.last());System.out.println("删除55->: " + treeSet.remove("55"));TreeSet< Integer> treeSet1 = new TreeSet();treeSet1.add(1);treeSet1.add(5);treeSet1.add(2);treeSet1.add(4);System.out.println("排序,不可重复->: " + treeSet1);//Str怎么遍历for (String s : treeSet) {System.out.println(s);}//迭代器for (Iterator<String> it = treeSet.iterator(); it.hasNext();) {String s = it.next();System.out.println(s);}//函数式treeSet1.forEach(s -> System.out.print(s + " "));}
}
/*
无序,不可重复->: [55, world, java, hello]
删除55->: [world, java, hello]
有序,不可重复->: [hello, world, java, 55]
排序,不可重复->: [55, hello, java, world]
最小值->: 55
最大值->: world
删除55->: true
排序,不可重复->: [1, 2, 4, 5]
hello
java
world
hello
java
world
1 2 4 5 
./

2、HashSet集合的底层原理

        思考:为什么HashSet集合中存储的数据是无序、不重复、无索引的?带着此问题去学习底层原理。

2.1 哈希值

  • 就是一和int 类型的随机值,Java中每个对象都一个哈希值。
  • Java中对象,都可以调用Obejct类提供的hashCode方法,返回该对象自己的哈希值。
  • public hashCode(); //返回对象的哈希码值

对象哈希值的特点

  • 同一个对象多次地调用HashCode() 方法返回的哈希值是相同的。
  • 不同的对象,它们的哈希值大概率不相等,但是也有可能会想等(哈希碰撞)
public class SetDemo2 {public static void main(String[] args) {String a = "hello";String b = "hello world";System.out.println(a.hashCode());System.out.println(b.hashCode());}
}
/*
99162322
1794106052*/

2.2 哈希表

  • HashSet是基于哈希表存储数据的。

哈希表

  • JDK8之前,哈希表 = 数组 + 链表
  • JDK8开始,哈希表  = 数组 + 链表 + 红黑树
  • 哈希表是一种增删改查数据,性能都较好的数据结构

JDK之前的哈希表:数组 + 链表

JDK8开始哈希表:数组 + 链表 + 红黑树

2.3 红黑树

从二叉树开始理解

解决方法

3、HashSet集合元素的去重操作.

public class Student {//属性private String name;private int age;private char sex;public Student(String name, int age, char sex) {this.name = name;this.age = age;this.sex = sex;}public Student() {}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public char getSex() {return sex;}public void setSex(char sex) {this.sex = sex;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", sex=" + sex +'}' + "\n";}
}
import java.util.HashSet;
public interface SetDemo3 {public static void main(String[] args) {Student s1 = new Student("小王", 18, '男');Student s2 = new Student("小王", 18, '男');Student s3 = new Student("小颜", 18, '女');//创建HashSet集合HashSet<Student> set = new HashSet<>();set.add(s1);set.add(s2);set.add(s3);System.out.println(set);  //发现并没有去重}
}
/*
[Student{name='小颜', age=18, sex=女}
, Student{name='小王', age=18, sex=男}
, Student{name='小王', age=18, sex=男}
]*/

发现上面完全相同并没有去重

解决方案:

import java.util.Objects;public class Student {//属性private String name;private int age;private char sex;public Student(String name, int age, char sex) {this.name = name;this.age = age;this.sex = sex;}public Student() {}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public char getSex() {return sex;}public void setSex(char sex) {this.sex = sex;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", sex=" + sex +'}' + "\n";}//重写hashCode()  方法 和 equals() 方法@Overridepublic boolean equals(Object o) {//1、判断对象是否是同一个对象 如果自己和自己相等,则返回trueif (this == o) return true;//2、判断对象是否是null 如果对象是null,则返回false//如果不是此类型的对象,则返回falseif (o == null || getClass() != o.getClass()) return false;//3、将参数转为Student类型 因为传入的参数是Object类型Student student = (Student) o;//4、比较属性是否相同return age == student.age && sex == student.sex && Objects.equals(name, student.name);}@Overridepublic int hashCode() {return Objects.hash(name, age, sex);}
}
import java.util.HashSet;
public interface SetDemo3 {public static void main(String[] args) {Student s1 = new Student("小王", 18, '男');Student s2 = new Student("小王", 18, '男');Student s3 = new Student("小颜", 18, '女');//创建HashSet集合HashSet<Student> set = new HashSet<>();set.add(s1);set.add(s2);set.add(s3);System.out.println(set);  //发现并没有去重}
}
/*
[Student{name='小王', age=18, sex=男}
, Student{name='小颜', age=18, sex=女}
]*/

4、LinkedHashSet集合的底层原理

缺点:牺牲了内存换来了有序的特点。

5、TreeSet集合

import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;@NoArgsConstructor
@AllArgsConstructor
@Data
public class Teacher implements Comparable<Teacher> {private String name;private int age;//薪水private double salary;@Overridepublic String toString() {return "Teacher{" +"name='" + name + '\'' +", age=" + age +", salary=" + salary +'}' + "\n";}//t2.compareTo(t1)//t2 == this//t1 = o;//规则如果是升序,则返回值应该为正数//规则如果是降序,则返回值应该为负数//如果返回值0,认为左右边相等@Overridepublic int compareTo(Teacher o) {return this.getAge() - o.getAge();//上面的去重了如果不想去重
//        if(this.getAge() == o.getAge()){
//            return 1;
//        }else if(this.getAge() > o.getAge()){
//            return 1;
//        }else{
//            return -1;
//        }}
}
import java.util.Comparator;
import java.util.TreeSet;public class SetDemo4 {public static void main(String[] args) {//目标:搞清楚TreeSet集合对自定义对象的排序Teacher t1 = new Teacher("小王", 18, 6000);Teacher t2 = new Teacher("光头强", 20, 5000);Teacher t3 = new Teacher("熊大", 19, 4000);Teacher t4 = new Teacher("小张", 18, 3000);//创建TreeSet集合//结论:TreeSet集合存储自定义对象时,要求对象必须实现Comparable接口,并重写compareTo方法//方法2、public TreeSet(Comparator<? super E> comparator) 自带比较器Comparator对象,指定排序规则TreeSet<Teacher> set = new TreeSet();set.add(t1);set.add(t2);set.add(t3);set.add(t4);System.out.println(set);System.out.println("利用方法2 降序");TreeSet<Teacher> set2 = new TreeSet(new Comparator<Teacher>() {@Overridepublic int compare(Teacher o1, Teacher o2) {return o2.getAge() - o1.getAge();//按照薪水
//                return o2.getSalary() - o1.getSalary();  //报错//改进1
//                if(o1.getSalary() > o2.getSalary()){
//                    return 1;
//                }else if(o1.getSalary() < o2.getSalary()){
//                    return -1;
//                }else{
//                    return 0;
//                }//改进2
//                return Double.compare(o1.getSalary(), o2.getSalary());}});//        上面代码简化形式set2.add(t1);set2.add(t2);set2.add(t3);set2.add(t4);System.out.println(set2);TreeSet<Teacher> set3 = new TreeSet<>(( o1,  o2) ->o1.getAge() - o2.getAge());}
}
/*
//利用方法1 升序
[Teacher{name='小王', age=18, salary=6000.0}
, Teacher{name='熊大', age=19, salary=4000.0}
, Teacher{name='光头强', age=20, salary=5000.0}
]
//利用方法2 降序
利用方法2 降序
[Teacher{name='光头强', age=20, salary=5000.0}
, Teacher{name='熊大', age=19, salary=4000.0}
, Teacher{name='小王', age=18, salary=6000.0}
]*/

6、总结

http://www.dtcms.com/a/568456.html

相关文章:

  • 单调栈的“近亲”:用 O(n) 的「单调队列」征服「滑动窗口最大值」
  • Buildroot构建Linux系统根文件系统
  • 在自动驾驶数据闭环中的特征工程应用(上)
  • 【具身智能】Spatial Forcing 论文笔记 如何隐式地为 VLA 注入 3D 空间感知能力
  • 多模态技术深度探索:融合视觉与语言的AI新范式
  • 自动化单mysql多实例库的全量迁移脚本-v2版本
  • [CARLA系列--04]如何在Carla中去调用传感器模型--相机篇
  • 【ASP.NET MVC 进阶】DataAnnotations 特性验证全解析:从基础到避坑,让数据校验像 “安检“ 一样靠谱
  • 做ppt兼职的网站有哪些北京中燕建设公司网站
  • webgl 顶点、片元着色器传参,绘制彩色三角形
  • 实验室安全教育与管理平台学习记录(八)特种设备安全
  • 浙江网站制作国外翻墙设计网站
  • 《神经网络与深度学习》学习笔记一
  • 超越蓝牙与Wi-Fi,UWB技术如何解锁手机下一波创新浪潮?
  • 【VPX650G】基于 VPX 系统架构的 JFM9VU13P FPGA+JFMQL100TAI 超宽带信号处理平台
  • 软考 系统架构设计师系列知识点之杂项集萃(190)
  • Linux信号(下):信号保存和信号处理
  • 仅需一部智能手机,在NVIDIA Isaac Sim中重建真实场景:终极实战指南
  • Spring设计模式刨根问底
  • 河南郑州做网站汉狮网站赚钱的方式
  • 不是万维网的网站如何注册公司抖音号
  • AI 赋能科研实践:从选题到发表的技术重构之路
  • 技术的秩序:IT资产与配置管理的现代重构
  • 告别布线噩梦:8公里LoRa边缘网关如何重构工业物联边界
  • Python 图像处理利器:Pillow 深度详解与实战应用
  • 【数据结构】:二叉树——顺序结构,链式结构的实现及相关操作
  • RS485转以太网串口服务器-串口设备联网的理想选择
  • 电动化筑基:智能社会的能源革命与产业重构
  • 【深度学习新浪潮】智能体在图像处理领域的技术突破与实践指南
  • 这是我做的网站吗汇云网站建设