从零学Java Set集合

Java Set集合

文章目录

  • [Java Set集合](#Java Set集合)
    • [1 Set 集合](#1 Set 集合)
    • [2 Set实现类](#2 Set实现类)
      • [2.1 HashSet【重点】](#2.1 HashSet【重点】)
      • [2.2 LinkedHashSet](#2.2 LinkedHashSet)
      • [2.3 TreeSet](#2.3 TreeSet)
    • [3 Comparator 自定义比较器](#3 Comparator 自定义比较器)

1 Set 集合

特点:无序无下标、元素不可重复。
方法:全部继承自Collection中的方法。

常用方法

java 复制代码
public class TestSet01 {
    public static void main(String[] args) {
        //创建集合
        Set<String> set = new HashSet<>();
        //1 添加
        set.add("苹果");
        set.add("香蕉");
        set.add("西瓜");
        set.add("菠萝");
        set.add("桃子");
        set.add("榴莲");
        //不能添加重复元素
        //set.add("苹果");
        System.out.println("元素个数: "+set.size());
        System.out.println("打印: "+set);
        //2 删除
        //2.1 删除单个元素
        //set.remove("西瓜");
        //2.2 清空
        //set.clear();
        //3 遍历
        //3.1 增强for
        for (String s : set) {
            System.out.println(s);
        }
        //3.2 迭代器
        Iterator<String> it = set.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }
        //4 判断
        //4.1 判断是否存在
        System.out.println(set.contains("榴莲"));
        //4.2 判断是否为空
        System.out.println(set.isEmpty());
    }
}

2 Set实现类

2.1 HashSet【重点】

存储结构 : 哈希表(数组+链表),基于hashCode、equals实现元素不重复。

存储过程

  1. 根据元素的hash值计算位置,如果这个位置没有元素直接加入。

  2. 如果有元素会调用equals进行确认,结果为true,拒绝后者存入,如果为false,形成链表。

常用方法:

java 复制代码
public class TestHashSet {
    static class Student {
        String name;
        int age;

        public Student() {
        }

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

        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
        /*
          重写规则:
            1 equals和hashCode要同时重写
            2 两个方法依据的属性保持一致
        */
        @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);
        }
    }

    public static void main(String[] args) {
        //创建集合
        HashSet<Student> hashSet = new HashSet<>();
        //创建三个学生对象
        Student s1 = new Student("小明", 18);
        Student s2 = new Student("小红", 28);
        Student s3 = new Student("小白", 21);
        Student s4 = new Student("小白", 21);
        //1 添加
        hashSet.add(s1);
        hashSet.add(s2);
        hashSet.add(s3);
        hashSet.add(s4);
        System.out.println("元素个数: "+hashSet.size());
        System.out.println("打印: "+hashSet);
        //2 删除
        //2.1 删除单个元素
        //hashSet.remove(s3);
        //System.out.println("删除后: "+hashSet);
        //2.2 清空
        //hashSet.clear();
        //3 遍历
        //3.1 增强for
        for (Student student : hashSet) {
            System.out.println(student);
        }
        //3.2 迭代器
        Iterator<Student> it = hashSet.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }
        //4 判断
        //4.1 判断是否存在某元素
        System.out.println(hashSet.contains(s1));
        //4.2 判断是否为空
        System.out.println(hashSet.isEmpty());
    }
}

2.2 LinkedHashSet

存储结构: 双向链表实现的HashSet,按照链表进行存储,即可保留元素的插入顺序。

常用方法: 与上方一致

java 复制代码
LinkedHashSet<Student> set = new LinkedHashSet<>();

2.3 TreeSet

存储结构: 红黑树,基于排序实现元素不重复。

  • 对集合元素自动排序。
  • 元素的类型必须实现Comparable接口,或自定义比较器。

二叉查找树:

  1. 一个节点最多只能有两个子节点
  2. 左节点都比根节点小, 右节点都比根节点大, 没有重复的
  3. 遍历:
    • 先序遍历(根左右);
    • 中序遍历(左根右);
    • 后序遍历(左右根);

红黑树 : 一种特殊的二叉平衡查找树

  1. 节点有黑色和红色
  2. 左右保证平衡

常用方法:

Java 复制代码
public class TestTreeSet {
    //静态内部类实现Comparable<?>接口
    static class Student implements Comparable<Student> {
        String name;
        int age;

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

        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }

        @Override
        public int compareTo(Student o) {
            int n1 = this.age-o.age;
            int n2 = this.name.compareTo(o.name);
            return n1==0?n1:n2;
        }
    }

    public static void main(String[] args) {
        //创建集合
        TreeSet<Student> treeSet = new TreeSet<>();
        //创建四个元素
        Student s1 = new Student("小明", 16);
        Student s2 = new Student("小红", 21);
        Student s3 = new Student("aaa", 19);
        Student s4 = new Student("bbb", 19);
        //1 添加
        treeSet.add(s1);
        treeSet.add(s2);
        treeSet.add(s3);
        treeSet.add(s4);
        System.out.println("个数: "+treeSet.size());
        System.out.println("打印: "+treeSet);
        //2 删除
        //treeSet.remove(s4);
        //System.out.println("删除后: "+treeSet);
        //3 遍历
        //3.1 增强for
        for (Student student : treeSet) {
            System.out.println(student);
        }
        //3.2 迭代器
        Iterator<Student> it = treeSet.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }
        //4 判断
        System.out.println(treeSet.contains(s4));
        System.out.println(treeSet.isEmpty());
    }
}

3 Comparator 自定义比较器

特点:

  • 元素自身提供的比较规则称为自然排序。
  • Comparator可以实现定制比较规则。
  • compare(o1,o2),如果返回值为0,则为重复元素。
  • 使用Comparator比较器,元素类型可不实现Comparable接口,并且优先级高于Comparable接口。
java 复制代码
//创建比较器,定制比较规则
Comparator<Student> cmp = new Comparator<Student>() {
    @Override
    public int compare(Student o1, Student o2) {
        int n1 = o1.name.compareTo(o2.name);
        int n2 = o1.age- o2.age;
        return n1==0?n2:n1;
    }
};
//创建集合
TreeSet<Student> treeSet = new TreeSet<>(cmp);

练习:

TreeSet实现字符串按照长度排序,如果长度相同,按照编码顺序。

eg:

java 复制代码
public class TestComparator {
    public static void main(String[] args) {
        //练习:TreeSet实现字符串按照长度排序,如果长度相同,按照编码顺序。
        //匿名内部类
        Comparator<String> cmp = new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                int n1 = o1.length()-o2.length();
                int n2 = o1.compareTo(o2);
                return n1==0?n2:n1;
            }
        };
        TreeSet<String> treeSet = new TreeSet<>(cmp);
        treeSet.add("aaaaa");
        treeSet.add("bbbbb");
        treeSet.add("aaa");
        treeSet.add("badssd");
        treeSet.add("xxxxxxxx");
        treeSet.add("aasbv");
        System.out.println(treeSet);
    }
}

res:

java 复制代码
[aaa, aaaaa, aasbv, bbbbb, badssd, xxxxxxxx]
相关推荐
星辰徐哥10 小时前
易语言网络通信编程基础:HTTP/HTTPS/TCP/UDP实战开发
开发语言·http·https·udp·tcp·易语言
爱吃大芒果10 小时前
Flutter for OpenHarmony 实战: mango_shop 通用组件库的封装与跨端复用
开发语言·flutter·dart
雨季66610 小时前
Flutter 三端应用实战:OpenHarmony “安全文本溢出处理调节器”
开发语言·前端·安全·flutter·交互
白宇横流学长10 小时前
基于Spring Boot的连锁电影院管理系统的设计与实现
java·spring boot·后端
小小码农Come on10 小时前
QT控件之QTabWidget使用
开发语言·qt
码农水水10 小时前
从 OpenFeign 到 RestClient:Spring Cloud 新时代的轻量化 HTTP 调用方案
java·运维·后端·spring·http·spring cloud·面试
晔子yy10 小时前
聊聊Java的内存模型
java·开发语言
难得的我们10 小时前
基于C++的区块链实现
开发语言·c++·算法
Acrelhuang10 小时前
工厂配电升级优选 安科瑞智能断路器安全提效又节能-安科瑞黄安南
大数据·运维·开发语言·人工智能·物联网
Go_Zezhou10 小时前
render快速部署网站和常见问题解决
运维·服务器·开发语言·python·github·状态模式