Set (存储无序,不可重复)
- Set接口中没有定义过新的方法,使用的都是Collecion中的方法
- 无序性 : 存储的数据在底层数组中并非按照数组索引的顺序添加,而是根据HashCode排序的
- 不可重复性 : 保证添加的元素安好equals()判断时,不能返回true,即相同元素只能添加一个
HashSet (底层:数组+链表)
- 添加元素的过程
- 向HashSet添加元素a,首先调用元素a所在类的hashCode()方法,计算其哈希值
- 此哈希值通过某种算法算出在HashSet底层数组中存放的位置(索引位置)
- 判断此位置是否已经有元素,如果没有则元素a添加成功。如果此位置上有其他元素b(或者以链表的形式存在的多个元素),则比较a和b的hash值
- 如果哈希值不同,则元素a,添加成功,如果哈希值相同,则再调用类的equals方法,如果返回true,则添加失败,如果返回false则元素a添加成功
- 在存储的时候,如果已有元素,则新元素按照七(JDK7.0)上八(JDK8.0)下的方式
- 向Set中添加的数据,其所在的类一定要重写HashCode()和equals()方法
重写的hashcode和equals尽可能的保持一致性,相同的对象有相同的散列码
LinkedHashSet
- LinkedHashSet作为HashSet的子类,在添加元素的时候,每个元素还维护了两个引用,记录次元素的前一个和后一个元素
- 对于频繁的遍历操作LinkedHashSet的效率要高于HashSet
TreeSet(红黑树)
- 添加的数据必须是同一对象
- 两种排序, 自然排序 和 定制排序
自然排序
public class Test2 {
public static void main(String[] args) {
Set set = new TreeSet<>();
set.add(new User("x",12));
set.add(new User("a",12));
set.add(new User("c",12));
set.add(new User("r",12));
set.add(new User("l",12));
set.add(new User("l",22));
Iterator iterator = set.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
}
public class User implements Comparable{
String name;
Integer age;
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return Objects.equals(name, user.name) &&
Objects.equals(age, user.age);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Object o) {
if (o instanceof User){
User user = (User) o;
return this.name.compareTo(user.name);
}else{
throw new RuntimeException("类型不一致");
}
}
}
定制排序
public class Test2 {
public static void main(String[] args) {
Comparator comparator = new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof User && o2 instanceof User){
User u1 = (User) o1;
User u2 = (User) o2;
return Integer.compare(u1.age,u2.age);
}else {
throw new RuntimeException("类型不一致");
}
}
};
Set set = new TreeSet<>(comparator);
set.add(new User("x",2));
set.add(new User("a",4));
set.add(new User("c",67));
set.add(new User("r",12));
set.add(new User("l",12));
set.add(new User("l",39));
Iterator iterator = set.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
}