Set系列集合
添加的元素是无序(存取顺序不一致),不重复(可以去除重复),无索引(不能使用普通for循环遍历,无带索引的方法)
Set集合的实现类
HashSet
无序 不重复 无索引
底层原理:
采用哈希表存储数据(哈希表的组成:数组+链表+红黑树)
HashSet基于HashMap实现。HashSet中的元素存储在HashMap的键上,而HashMap中的键是唯一的,因此HashSet中的元素也是唯一的。
在HashSet中,所有元素都被映射到HashMap的键上,而对应的值都是一个固定的常量(比如PRESENT
)。
哈希值:对象的整数表现形式
1.根据hashCode方法算出来的int类型的整数
2.该方法定义在Object类中,所有对象都可以调用,默认使用地址值进行计算
3.一般情况下,会重写hashCode方法,利用对象内部的属性值计算哈希值
测试代码
public class HashSetTest1 {
//利用HashSet集合去除重复元素
/*
创建一个存储学生对象的集合 存储多个学生对象
使用程序实现在控制台遍历该集合
要求:学生对象的成员变量值相同 我们就认为是同一个对象
*/
public static void main(String[] args) {
//创建学生对象
Student s1 = new Student("jack", 12);
Student s2 = new Student("tom", 13);
Student s3 = new Student("peter", 11);
Student s4 = new Student("jack", 12);
//创建集合用来添加学生
Set<Student> set = new HashSet<>();
System.out.println(set.add(s1)); //t
System.out.println(set.add(s2)); //t
System.out.println(set.add(s3)); //t
System.out.println(set.add(s4)); //f
//打印集合
System.out.println(set);
}
}
LinkedHashSet
有序 不重复 无索引
这里的有序指的是保证存储和取出的元素顺序一致
底层原理
底层数据结构依然是哈希表,只是每个元素有额外多了一个双链表的机制记录存储的顺序
LinkedHashSet继承自HashSet,它在HashSet的基础上增加了链表来维护元素的插入顺序。
LinkedHashSet内部使用LinkedHashMap来实现,HashMap的键对应着LinkedHashSet中的元素,而HashMap中的值则被设为一个固定的常量(如PRESENT
)。
因为LinkedHashMap维护了插入顺序,所以LinkedHashSet能够保持元素的插入顺序。
package itemCollection;
import java.util.LinkedHashSet;
import java.util.Objects;
import java.util.Set;
/**
* @author hyk~
*/
public class LinkedHashSetDemo1 {
public static void main(String[] args) {
//创建学生对象
Set<Student> lhs = new LinkedHashSet<>();
lhs.add(new Student("li",10));
lhs.add(new Student("hua",12));
lhs.add(new Student("zen",18));
lhs.add(new Student("gui",6));
System.out.println(lhs); //存和取的顺序相同
//[Student{name='li', age=10}, Student{name='hua', age=12}, Student{name='zen', age=18}, Student{name='gui', age=6}]
}
}
class Student implements Comparable<Student>{
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
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;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age && Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
@Override
public String toString() {
return "学生姓名:"+name+" 学生年龄:"+age;
}
@Override
public int compareTo(Student o) {
//指定排序的规则
//只看年龄,按照年龄的升序进行排序
return this.getAge() - o.getAge();
}
}
TreeSet
可排序 不重复 无索引
可排序:按照元素的默认规则(由小到大)
TreeSet集合底层是基于红黑树的数据结构实现排序的,增删改查的性能都较好
底层原理
TreeSet是基于红黑树(Red-Black Tree)实现的,它可以保持元素的排序状态。
TreeSet中的元素是按照键的自然顺序或者通过比较器对象来进行排序的。
TreeSet如何实现排序:http://t.csdnimg.cn/FKpZy
红黑树保证了元素的添加、删除和查找操作的时间复杂度都是O(log n),其中n是元素个数。