Set集合

Set集合存储特点:无序、不可重复。
无序是指存储顺序与添加顺序可能不一样;不允许存储重复的数据;

相应Api用法可参考Collection集合 - 鹿先森JIAN - 博客园 (cnblogs.com)

下面分别介绍 HashSet、LinkedHashSet、TreeSet 的用法。

查看 HashSet 源码发现在 HashSet 的无参构造方法中创建了 HashMap 集合, 所以 HashSet 底层是 HashMap。

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
// Set集合 特点:无序,不重复
public class SetTest {
    public static void main(String[] args) {
        Set<String> set = new HashSet<>();
        set.add("abcde");
        set.add("123");
        set.add("123"); // 添加重复数据,加不了滴!
        set.add("hello");
        set.add("xx");
        //打印结果跟添加顺序不一样(即无序)
        System.out.println(set); // [xx, 123, abcde, hello]
        System.out.println(set.size()); // 4
        // 删除指定元素
        set.remove("xx");
        // 迭代
        Iterator<String> iterator = set.iterator();
        while (iterator.hasNext()){
            String s = iterator.next();
            System.out.print(s+"\t");
        }   // 123    abcde    hello  
/*
        // foreach 习惯用于无索引的数据输出
        for (String i:set ) {
            System.out.print(i+"\t");
        }
*/
    }
}

HashSet如果存储自定义类型对象,contains(o)、remove(o) 方法会调用对象的 equals()方法。

在自定义类型中需要重写 equals()、hashCode();所有带 Hash 字样的集合都需要用到哈希码。

// 自定义一个 Student 类
import java.util.Objects;

public class Student {
    private String name;
    private int age;

    // 提供 getter、setter方法、无参有参构造
    public String getName() {    return name;    }
    public void setName(String name) {    this.name = name;    }

    public int getAge() {    return age;    }
    public void setAge(int age) {    this.age = age;    }

    public Student() { }
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // Alt+insert,重写 toString、equals、hashCode 方法
    @Override
    public String toString() {
        return "Student{" + "name='" + name + '\'' + ", age=" + age + '}';
    }
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age && Objects.equals(name, student.name);
    }
    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}
import java.util.HashSet;
// 测试类
public class SetTest01 {
    public static void main(String[] args) {
        Student s1 = new Student("zs", 18);
        Student s2 = new Student("zs", 18);
        // 存储自定义类型对象
        HashSet<Student> students = new HashSet<>();
        students.add(s1);
        students.add(s2);
        System.out.println(students); // [Student{name='zs', age=18}]
/* 虽然s1,s2的地址值不同,但是s1,s2的内容是一样的。
* Student类重写了 equals()、hashCode()方法,就是拿来比较内容的;
* 内容一样就不会再被放进去了 
* */
    }
}

----------------------------------------------------------

LinkedHashSet<E> 继承了 HashSet<E>,具有可预知迭代顺序Set 接口的哈希表和链接列表实现。此实现与 HashSet 的不同之外在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,即按照将元素插入到 set 中的顺序(插入顺序)进行迭代。换句话说,LinkedHashSet 也是无序存储不重复元素的,但是它的打印结果可以跟添加顺序一样!

import java.util.LinkedHashSet;

public class SetTest06 {
    public static void main(String[] args) {
        LinkedHashSet<String> hashSet = new LinkedHashSet<>();
        hashSet.add("hello");
        hashSet.add("java");
        hashSet.add("java");
        hashSet.add("world");
        System.out.println(hashSet); // [hello, java, world]
    }
}

----------------------------------------------------

TreeSet实现了SortedSet接口, 可以对集合中的元素自然排序, 要求集合中的元素必须可比较大小。

TreeSet 的用法 - 鹿先森JIAN - 博客园 (cnblogs.com)

posted @ 2022-04-27 21:53  鹿先森JIAN  阅读(29)  评论(0编辑  收藏  举报