**Set集合**
一个不包含重复元素的collection
**Set案例**
储存字符串并遍历
储存自定义对象并遍历
**特点**
**Collection**
**|--List**
有序(存储顺序和取出顺序一致),可重复
|–Set
无序(存储顺序和取出顺序不一致),唯一
Collection
|–List
有序(存储顺序和取出顺序一致),可重复
|–Set
无序(存储顺序和取出顺序不一致),唯一
HashSet:它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。
注意:
虽然Set集合的元素无序,但是,作为集合来说,它肯定有它自己的存储顺序,
而你的顺序恰好和它的存储顺序一致,这代表不了有序,你可以多存储一些数据,就能看到效果。
/
public class SetDemo {
public static void main(String[] args) {
// 创建集合对象
Set<String> set = new HashSet<String>();
// 创建并添加元素
set.add("hello");
set.add("java");
set.add("world");
set.add("java");
set.add("world");
// 增强for
for (String s : set) {
System.out.println(s);
}
}
}
注意
虽然Set集合的元素无序,但是,作为集合来说,它肯定有它自己的存储顺序,
而你的顺序恰好和它的存储顺序一致,这代表不了有序,你可以多存储一些数据,就能看到效果。
HashSet:它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。
HashSet类
不保证set的迭代顺序
特别是他不保证该顺序恒久不变
如何保证元素的唯一性
底层数据结构是哈希表
哈希表依赖于哈希值储存
添加功能底层依赖两个方法
2.1.存储自定义对象,并保证元素的唯一性
你使用的是HashSet集合,这个集合的底层是哈希表结构。
而哈希表结构底层依赖:hashCode()和equals()方法。
如果你认为对象的成员变量值相同即为同一个对象的话,你就应该重写这两个方法。
如何重写呢? 不同担心,自动生成即可。
/*
-
需求:存储自定义对象,并保证元素的唯一性
-
要求:如果两个对象的成员变量值都相同,则为同一个元素。
-
目前是不符合我的要求的:因为我们知道HashSet底层依赖的是hashCode()和equals()方法。
-
而这两个方法我们在学生类中没有重写,所以,默认使用的是Object类。
-
这个时候,他们的哈希值是不会一样的,根本就不会继续判断,执行了添加操作。
*/
public class demo {
public static void main(String[] args) {
// 创建集合对象
Set hs = new HashSet();// 创建学生对象 Student s1 = new Student("江一燕", 27); Student s2 = new Student("柳岩", 22); Student s3 = new Student("王祖贤", 30); Student s4 = new Student("江一燕", 27); Student s5 = new Student("江一燕", 27); Student s6 = new Student("范冰冰", 22); // 添加元素 hs.add(s1); hs.add(s2); hs.add(s3); hs.add(s4); hs.add(s5); hs.add(s6); // 遍历集合 for (Student s : hs) { System.out.println(s.getName() + "---" + s.getAge()); }}
}
public class Student {
// 成员变量
private String name;
private int age;
// 构造方法
public Student() {
super();
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
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;
}
计算机中数据的比较可以分两种情况:
1>值比较(用equals()方法)
2>内存地址比较(用hashCode()方法)
当然上面的无论是equals()还是hashCode()你都可以重写
Set (不允许放重复值),它的比较标准就是:
1>比较equls(),如果相等,就判定它们相等;
2>如果equls()不相等,就比较hashCode()
如果hashCode()相等,就判定这两个对象相等,否则不相等
equls()是判定得第一标准
hashCode()是第二标准
//解决如果两个对象的成员变量值都相同,则为同一个元素,只保存一个对象
@Override
public int hashCode() {
final int prime = 31;//这里的数字最好是一个质数,这里设计到一个哈希表的查找
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
//生成快捷键alt+shift+s
3.LinkedHashset类
概述:1.元素有序唯一2.由链表保证元素有序3.由哈希表保证元素唯一
/*
-
LinkedHashSet:底层数据结构由哈希表和链表组成。
-
哈希表保证元素的唯一性。
-
链表保证元素有素。(存储和取出是一致)
*/
public class LinkedHashSetDemo {
public static void main(String[] args) {
// 创建集合对象
Set hs = new LinkedHashSet();// 创建并添加元素 hs.add("hello"); hs.add("world"); hs.add("java"); hs.add("world"); hs.add("java"); // 遍历 for (String s : hs) { System.out.println(s); }}
}
4.Treeset类
概述:1.使用元素的自然顺序对元素进行排序
2.或者根据创建set时提供的 Comparator进行排序
3.具体取决于使用的构造方法
无参构造是自然排序
/* -
TreeSet:能够对元素按照某种规则进行排序。
-
排序有两种方式
-
A:自然排序
-
B:比较器排序
-
TreeSet集合的特点:排序和唯一
-
通过观察TreeSet的add()方法,我们知道最终要看TreeMap的put()方法。TreeSet底层执行的就是TreeMap
*/
public class TreeSetDemo {
public static void main(String[] args) {
// 创建集合对象
// 自然顺序进行排序
Set ts = new TreeSet();// 创建元素并添加 // 20,18,23,22,17,24,19,18,24 ts.add(20); ts.add(18); ts.add(23); ts.add(22); ts.add(17); ts.add(24); ts.add(19); ts.add(18); ts.add(24); // 遍历 for (Integer i : ts) { System.out.println(i); }}
}
4.1.1.分析TreeSet原理
4.1.2.TreeSet存储自定义对象
/*
*** TreeSet存储自定义对象并保证排序和唯一。
*
- A:你没有告诉我们怎么排序
-
自然排序,按照年龄从小到大排序 - B:元素什么情况算唯一你也没告诉我
-
成员变量值都相同即为同一个元素
*/**
public class demo {
public static void main(String[] args) {
// 创建集合对象
Set<Student> ts = new TreeSet<Student>();
// 创建元素
Student s1 = new Student("linqingxia", 27);
Student s2 = new Student("zhangguorong", 29);
Student s3 = new Student("wanglihong", 23);
Student s4 = new Student("linqingxia", 27);
Student s5 = new Student("liushishi", 22);
Student s6 = new Student("wuqilong", 40);
Student s7 = new Student("fengqingy", 22);
// 添加元素
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
ts.add(s5);
ts.add(s6);
ts.add(s7);
// 遍历
for (Student s : ts) {
System.out.println(s.getName() + "---" + s.getAge());
}
}
}
//如果一个类的元素要想进行自然排序,就必须实现自然排序的接口
public class Student implements Comparable{
// 成员变量
private String name;
private int age;
@Override
public int compareTo(Student s) {
//按照年龄排序 ,主要条件
int num = this.age - s.age;
int num2 = num == 0 ? this.name.compareTo(s.name) : num ;
return num2;
}
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
本文深入解析Java中的Set集合,包括HashSet、LinkedHashSet和TreeSet的特点与应用。探讨了集合的无序性和唯一性,以及如何通过哈希表和链表保证元素的存储特性。同时,分析了TreeSet如何实现元素的自然排序和比较器排序。
8626

被折叠的 条评论
为什么被折叠?



