存储无序的、不可重复的数据
一般用于过滤重复数据
存储原理
根据哈希算法值确定元素的内存位置,当内存位置一致时,先比较hash值,当hash值一致时,将元素进行equals对比,不相同时才放入set中;同一个内存位置的元素以链表形式存储
实现类
HashSet
底层就是HashMap实现的;即使用数组+单向链表+红黑树结构进行存储(jdk8中引入红黑树)
LinkedHasSet
HashSet的子类,底层就是LinkedHashMap实现的;即现用数组+单向链表+红黑树的基础上,又添加了一组双向链表,用于记录添加元素的先后顺序;即我们可以按照添加元素的顺序实现遍历;便于频繁的查询操作
TreeSet
底层就是TreeMap实现的;使用红黑树存储。可以按照添加的元素的指定的属性大小顺序进行遍历
添加元素必须是相同类型的,否则会报错ClassCaseException
元素所在类需要实现Comparable接口/使用Comparator接口比较,不需要重写hashCode()和equals()
使用Comparable的compareTo方法/使用Comparator接口的compare方法返回的值进行比较进行重复判断,后一个相等的元素不能添加进TreeSet
不再使用hashCode()和equals()方法判断重复
自然排序
class Personal implements Comparable {
private String name;
private int age;
public Personal(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int compareTo(Object o) {
}
}
public void test() {
TreeSet t = new TreeSet();
t.add(new Personal("Tom", 23));
t.add(new Personal("Jack", 23));
t.add(new Personal("Lijie", 18));
Iterator iterator = t.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
自定义排序
class Personal {
private String name;
private int age;
public Personal(String name, int age) {
this.name = name;
this.age = age;
}
}
public void test() {
Comparator comparator = new Comparator() {
@Override
public int compare(Object o1, Object o2) {
}
};
TreeSet t = new TreeSet(comparator);
t.add(new Personal("Tom", 23));
t.add(new Personal("Jack", 23));
t.add(new Personal("Lijie", 18));
Iterator iterator = t.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
理解无序的、不可重复的
无序性
不等于随机性
也不是添加顺序与遍历顺序不一致
不想ArrayList一样是依次紧密排列的
因为根据哈希算法值确定的内存位置不确定,体现无序性
添加添加的元素的哈希值,计算其在数组中的存储位置,此位置不是依次排列的,表现为无序性
不可重复性
添加到set中的元素时不能相同的,比较的标准,需要判断hashCode()得到的hash值与equals()得到的结果
hash值相同且equals()返回true,则认为元素是相同的
添加到HashSet、LinkedHashSet中元素的要求
要求元素所在的类要重写两个方法,equals()和hashcCde()
要求equals()和hashCode()要保持一致性,使用Idea自动生成即可,就能保证一致性
添加进set的元素,修改其元素对象信息时会修改成功,但是其内存位置是根据第一次存放时对象的hash值计算得到的,信息更改后,内存位置不会变