HashSet、TreeSet、LinkedHashSet的区别

简介: HashSet、TreeSet、LinkedHashSet的区别

HashSet、TreeSet、LinkedHashSet的区别

1、HashSet

1.实现方式:基于哈希表(HashMap)实现

2.不允许重复,可以有一个null元素

3.不保证顺序恒久不变

4.添加元素时把元素作为HashMap的key存储,HashMap的value使用一个固定的Object对象

5.排除重复元素是通过equals来判断元素是否相同

6.判断两个对象是否相同,先判断两个对象的hashCode是否相同(如果两个对象的hashcode相同,不一定是同一个对象,如果不同,那一定不是同一个对象),如果不同,则两个对象不是同一个对象,如果相同还要进行equals判断,equals相同则是同一个对象,不同则不是同一个对象

7.自定义对象要重写hashcode方法和equals对象

小结:

(1)哈希表的存储结构:数组加链表,数组里的每个元素以链表的形式存储

(2)如何把对象存储到哈希表中,先计算对象的hashCode值,再对数组的长度求余数,来决定对象要存储在数组中的哪个位置

(3)解决hashSet中的重复值使用的方式是,参考第6点

基本使用:

写一个实体类(重新equals和hashcode方法)

class Cat {
    private String name;
    private int age;
    private int id;
    public Cat(String name, int age, int id) {
        this.name = name;
        this.age = age;
        this.id = id;
    }
    // get,set,toString()
    // 需要重写hashcode()和equals()方法
    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        Cat cat = (Cat) o;
        return age == cat.age && id == cat.id && name.equals(cat.name);
    }
    @Override
    public int hashCode() {
        return Objects.hash(name, age, id);
    }
}

使用HashSet:

private static void hashSet() {
        Set<String> set = new HashSet<>();
        set.add("飞飞");
        set.add("亮亮");
        // 不可重复
        set.add("亮亮");
        set.add("关关");
        set.add("曹操");
        set.add("备备");
        set.add(null);
        set.add(null);
        String[] strings = set.toArray(new String[]{});
        for (String s : strings
        ) {
            System.out.println(s);
        }
        Cat c1 = new Cat("miaomiao", 4, 1);
        Cat c2 = new Cat("huahua", 3, 2);
        Cat c3 = new Cat("tom", 5, 3);
        // 需要重写hashcode()方法和equals方法
        Cat c4 = new Cat("tom", 5, 3);
        Set<Cat> cats = new HashSet<>();
        cats.add(c1);
        cats.add(c2);
        cats.add(c3);
        cats.add(c4);
        //cats.add(c4);
        System.out.println(cats.size());
    }

2、TreeSet

1、有序的,基于TreeMap(二叉树数据结构),对象需要比较大小,通过对象比较器来实现

2、对象比较器还可以用来去除重复元素,如果自定义的类,没有实现比较器接口,将无法添加到TreeSet集合中

基本使用:

*/
    private static void treeSet() {
        Cat c1 = new Cat("miaomiao", 4, 1);
        Cat c2 = new Cat("huahua", 3, 2);
        Cat c3 = new Cat("tom", 5, 3);
        Cat c4 = new Cat("Tom", 4, 1);
        //指定排序规则,先按照id,再年龄,再姓名
        Set<Cat> cats = new TreeSet<>((o1, o2) -> {
            if (o1.getId() != o2.getId()) {
                return o1.getId() - o2.getId();
            }
            if (o1.getAge() != o2.getAge()) {
                return o1.getAge() - o2.getAge();
            }
            return o1.getName().compareTo(o2.getName());
        });
        cats.add(c1);
        cats.add(c2);
        cats.add(c3);
        cats.add(c4);
        System.out.println(cats);
    }

3、LinkedHashSet

1、哈希表和链表列表来实现

2、维护着一个运行与所有条目的双重链表列表,此链表定义了迭代顺序,即按照将元素插入到set中的顺序(插入顺序)进行迭代

简单使用:

private static void linkedHashSet(){
        Cat c1 = new Cat("miaomiao", 4, 1);
        Cat c2 = new Cat("huahua", 3, 2);
        Cat c3 = new Cat("tom", 5, 3);
        Cat c4 = new Cat("Tom", 4, 1);
        Set<Cat> cats = new LinkedHashSet<>();
        cats.add(c1);
        cats.add(c2);
        cats.add(c3);
        cats.add(c4);
        System.out.println(cats);
    }

4、如何选择?

如果要排序,选择TreeSet

如果不要排序,也不要保证顺序,选择HashSet

如果不要排序,要保证顺序,选择LinkedHashSet

目录
相关文章
|
4月前
|
存储
HashSet的使用
HashSet的使用
35 2
|
5月前
|
存储
HashSet和LinkedHashSet使用
HashSet和LinkedHashSet使用
|
7月前
|
容器
HashSet
HashSet
46 0
|
存储 算法
TreeSet 和 HashSet 的区别
TreeSet 和 HashSet 的区别
62 0
|
存储 安全
HashSet和HashMap
HashSet和HashMap
122 0
|
存储 安全 容器
HashSet详解
HashSet详解
174 0
HashSet详解
|
存储 安全 API
TreeSet详解
TreeSet详解
172 0
TreeSet详解
|
存储 容器
LinkedHashSet详解
LinkedHashSet详解
191 0
LinkedHashSet详解
|
存储
TreeSet相关问题
TreeSet相关问题
114 0