Set

Set集合的特点

HashSet:无序;不重复;无索引
LinkedHashSet:有序;不重复;无索引
TreeSet:可排序(默认升序);不重复;无索引

HashSet

  • 基于哈希表实现
  • 哈希表是一种增删改查数据,性能都比较好的数据结构

哈希表:JDK8之前,哈希表=数组+链表 JDK8之后,哈希表=数组+链表+红黑树

JDK8之前

HashSet扩容

HashSet去重复问题

示例代码如下

import lombok.AllArgsConstructor;
import lombok.Data;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

/**
 * @author Pickle
 * @version V1.0
 * @date 2024/3/9 13:57
 */

@AllArgsConstructor
class Student{
    private String name;
    private Integer age;
    private Double height;

    @Override
    public String toString() {
        return this.name + " " + this.age + " " + this.height;
    }
}
public class SetDemo {
    public static void main(String[] args) {
        Set<Student> set = new HashSet<>();
        set.add(new Student("小明",11,180.0));
        set.add(new Student("小明",11,180.0));
        set.add(new Student("小明",11,180.0));
        final Iterator<Student> iterator = set.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }
}

打印结果

Set集合中出现了三个一摸一样的对象

解决方法,重写Student的hashCode和equals方法,因为Student默认的equals继承的Object方法对比的是内存地址,所以认为是三个不同的对象

重写Student类的equals和hashCode方法问题解决

LinkedHashSet

  • LinkedHashSet依然是基于哈希表(数组,链表,红黑树)实现的
  • 但是,他的每个元素都额外的多了一个双链表的机制记录他前后元素的位置。

TreeSet

import com.sun.source.tree.Tree;

import java.util.LinkedHashSet;
import java.util.Set;
import java.util.TreeSet;

/**
 * @author Pickle
 * @version V1.0
 * @date 2024/3/9 14:57
 */
public class LinkedHashSetDemo {
    public static void main(String[] args) {
        //底层是基于红黑树排序
        Set<Integer> set = new TreeSet<>();
        set.add(6);
        set.add(5);
        set.add(7);
        set.add(4);
        set.add(10);
        System.out.println(set);

    }
}

红黑树的插入过程


比如下面的代码

import com.sun.source.tree.Tree;
import lombok.AllArgsConstructor;

import java.util.*;

/**
 * @author Pickle
 * @version V1.0
 * @date 2024/3/9 14:57
 */
@AllArgsConstructor
class Student{
    private String name;
    private Integer age;
    private Double height;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        //这里错误的比较,因为字段都是引用类型的变量,下边的代码一定是返回False的
        //return name==student.name &&age==student.age&& height==student.height;
        return Objects.equals(name,student.name) && Objects.equals(height, student.height)&&Objects.equals(age,student.age);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age, height);
    }

    @Override
    public String toString() {
        return this.name + " " + this.age + " " + this.height;
    }
}
public class LinkedHashSetDemo {
    public static void main(String[] args) {
        //底层是基于红黑树排序
        Student s1 = new Student("A",11,180.0);
        Student s2 = new Student("B",12,180.0);
        Student s3 = new Student("C",13,180.0);
        Set<Student> set = new TreeSet<>();
        set.add(s1);
        set.add(s2);
        set.add(s3);
        System.out.println(set);

    }
}

直接报错,原因是他不知道Student应该怎么排序,所以应该实现Comparable接口重写compare方法

posted @ 2024-03-09 15:28  破忒头头  阅读(34)  评论(0)    收藏  举报