Set接口 (集合续)
set继承了collection接口
Set中所存储的元素是不重复的,但是是无序的, Set中的元素是没有索引的
Hashset 无序的 不可重复 不是按照添加顺序打印的 哈希表/链表
Treeset 有序的 不可重复
Set接口有两个实现类
HashSet
HashSet类中的元素不能重复,即彼此调用equals方法比较,都返回false。
-
底层数据结构是哈希表+链表
-
哈希表依赖于哈希值存储
向hashSet中添加元素时是如何判定重复元素?
底层是双保险的: 既要提高判断效率,还要安全可靠
首先会获得 添加内容hash值,判断哈希值在集合中是否存在
但是内容不同时 hash值可能会相同, 那么就不可靠
在hash值相同时会 调用equals() 比较内容是否相等
package day3;
import java.util.HashSet;
import java.util.Set;
public class SetDemo {
public static void main(String[] args) {
/*
set继承了collection接口
Set中所存储的元素是不重复的,但是是无序的, Set中的元素是没有索引的
Hashset 无序的 不可重复 不是按照添加顺序打印的 哈希表/链表
Treeset 有序的 不可重复
*/
/*int [] a={1,2,3,};
public native int Hashcode();
[I@1b6d3586 默认调用时object类中toString() 调用Object类中HashCode()
System.out.println(a);*/
/*
* 如果类中没有重写hashcode(),那么会调用Object类中的hashcode() 算出对象的哈希值
* */
//Student student=new Student();
//System.out.println(student);
/*
向hashSet中添加元素时是如何判定重复元素?
底层是双保险的: 既要提高判断效率,还要安全可靠
首先会获得 添加内容hash值,判断哈市值在集合中是否存在
但是内容不同时 hash值可能会相同, 那么就不可靠
在hash值相同时会 调用equals() 比较内容是否相等
*/
/* HashSet<String> set=new HashSet();
set.add("a");
set.add("s");
set.add("萨克斯");
set.add("a");
set.add("沙拉");
set.add("z");
System.out.println(set);*/
HashSet<Student> set1 =new HashSet();
//如果类中没有重写hashcode(),那么会调用Object类中的hashcode()(不会重复) 算出对象的哈希值
Student s1=new Student(101,"jim1");
Student s2=new Student(101,"jim1");
Student s3=new Student(103,"jim3");
Student s4=new Student(104,"jim4");
set1.add(s1);
set1.add(s2);
set1.add(s3);
set1.add(s4);
System.out.println(set1);
}
}
TreeSet
-
可以给Set集合中的元素进行指定方式的排序。存储的对象必须实现Comparable接口。
-
TreeSet底层数据结构是二叉树(红黑树是一种自平衡的二叉树)
特点:
不可存储重复元素
有序(按自然顺序排列) 数据类型 实现comparable()接口 重写compareTo()
treeset调用CompareTo() 比较元素大小
package day3;
import java.util.TreeSet;
public class TreeSetDemo {
public static void main(String[] args) {
/*
treeSet:
不可存储重复元素
有序(按自然顺序排列) 数据类型 实现comparable()接口 重写compareTo()
treeset调用CompareTo() 比较元素大小
*/
TreeSet<String> set=new TreeSet<>();
set.add("a");
set.add("w");
set.add("a");
set.add("q");
set.add("v");
set.add("x");
System.out.println(set);
TreeSet<Integer> set1=new TreeSet<>();
set1.add(6);
set1.add(5);
set1.add(7);
set1.add(16);
set1.add(2);
set1.add(1);
System.out.println(set1);
TreeSet<Student> students=new TreeSet<>();
students.add(new Student(101,"华磊1"));
students.add(new Student(102,"华磊3"));
students.add(new Student(103,"华磊4"));
students.add(new Student(101,"华磊2"));
System.out.println(students);
}
}
package day3;
import java.util.Objects;
public class Student implements Comparable<Student> {
private int xh;
private String name;
public int getXh() {
return xh;
}
public void setXh(int xh) {
this.xh = xh;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Student(int xh, String name) {
this.xh = xh;
this.name = name;
}
/*
当hash值出现重复时会调用equals() 进行内容的判断,效率低 安全
*/
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Student)) return false;
Student student = (Student) o;
return xh == student.xh &&
Objects.equals(name, student.name);
}
/*
重写Object类中hashCode(),来自己根据对象中包含的内容计算hash值
效率高
目的是为了删除重复元素 如果不重写hashCode(),那么将默认调用Object类中的hashCode(),即使
对象中的内容相同,但是他们对象地址不同,所以要重写hashCode()以便于判断他们的内容是否相等(删除重复元素)
*/
@Override
public int hashCode() {
return Objects.hash(xh, name);
}
@Override
public String toString() {
return "Student{" +
"xh=" + xh +
", name='" + name + '\'' +
'}';
}
@Override
public int compareTo(Student o) {
return this.xh-o.xh; //调用compareTo()比较元素大小
//return this.name.hashCode()-o.name.hashCode();
}
}