Set集合

  • HashSet (哈希表) 唯一,无序;添加、删除、查询速度快
  • LinkedHashSet (哈希表+链表) 唯一,有序(添加顺序);比哈希表慢点
  • TreeSet 红黑树(一种二叉平衡树)唯一,有序(自然顺序);查询速度(按内容查)比List快,没HashSet 哈希表快
  • List针对Collection增加了一些对索引的操作方法,如add(1),remove(1),get(1),set(1,"A")
  • Set是无序的,不能增加对索引操纵的方法,Set针对Collection没有增加任何方法
  • List的遍历方式:for循环,for-each循环,Iterator迭代器,流式编程forEach
  • Set的遍历方式:for-each循环,Iterator迭代器,流式编程forEach
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

public class SetDemo01 {
    public static void main(String[] args) {
        Set<String> set = new TreeSet();
        set.add("JavaSE");
        set.add("JavaEE");
        set.add("MySql");
        set.add("Html");
        set.add("JavaSE");
        System.out.println(set);//[Html, JavaEE, JavaSE, MySql]  唯一,自然顺序
        System.out.println(set.size());// 4
        System.out.println("=============遍历方法一:for-each=============");
        for (String elem : set) {
            System.out.println(elem);
        }
        System.out.println("=============遍历方法二:迭代=============");
        Iterator<String> iterator = set.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
        System.out.println("=============遍历方法三:拉姆达表达式+流式编程=============");
        set.forEach(item -> System.out.println(item));
    }
}

执行结果:
[Html, JavaEE, JavaSE, MySql]
4
=============遍历方法一:for-each=============
Html
JavaEE
JavaSE
MySql
=============遍历方法二:迭代=============
Html
JavaEE
JavaSE
MySql
=============遍历方法三:拉姆达表达式+流式编程=============
Html
JavaEE
JavaSE
MySql

Process finished with exit code 0

1.创建一个学生类存到Set中

1.1先创建Student类
package com.zhang.setdemo;

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

    public Student() {
    }

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

    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;
    }

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

1.2.创建测试类
package com.zhang.setdemo;

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


public class SetDemo01 {
    public static void main(String[] args) {
        Set<Student> set = new HashSet();
        Student stu1 = new Student("zhangsan", 20);
        Student stu2 = new Student("lisi", 23);
        Student stu3 = new Student("wangwu", 23);
        Student stu4 = new Student("zhangsan", 20);
        set.add(stu1);
        set.add(stu2);
        set.add(stu3);
        set.add(stu4);
        System.out.println(set);
        //[Student{name='wangwu', age=23}, Student{name='lisi', age=23}, Student{name='zhangsan', age=20}, Student{name='zhangsan', age=20}]
        Set<Student> set2 = new LinkedHashSet();
        Student stu11 = new Student("zhangsan", 20);
        Student stu22 = new Student("lisi", 23);
        Student stu33 = new Student("wangwu", 23);
        Student stu44 = new Student("zhangsan", 20);
        set2.add(stu11);
        set2.add(stu22);
        set2.add(stu33);
        set2.add(stu44);
        System.out.println(set2);
        //[Student{name='zhangsan', age=20}, Student{name='lisi', age=23}, Student{name='wangwu', age=23}, Student{name='zhangsan', age=20}]
        Set<Student> set3 = new TreeSet();
        Student stu111 = new Student("zhangsan", 20);
        Student stu222 = new Student("lisi", 23);
        Student stu333 = new Student("wangwu", 23);
        Student stu444 = new Student("zhangsan", 20);
        set3.add(stu111);
        set3.add(stu222);
        set3.add(stu333);
        set3.add(stu444);
        System.out.println(set3);//java.lang.ClassCastException: Student cannot be cast to java.lang.Comparable
    }
}

运行发现
  • 问题1.HashSet和LinkedHashSet存储String是唯一的,但是存储Student不唯一
  • 问题2.TreeSet存储String是有序的,但是存储Student报异常:java.lang.ClassCastException: Student cannot be cast to java.lang.Comparable
解决方法:
  • 问题1解决方法

1.在Student类重写equals和hashCode,缺一不可

 @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);
    }

再次运行发现:HashSet和LinkedHashSet的结果唯一。
HashSet的结果:[Student{name='lisi', age=23}, Student{name='zhangsan', age=20}, Student{name='wangwu', age=23}]
    
LinkedHashSet的结果:[Student{name='zhangsan', age=20}, Student{name='lisi', age=23}, Student{name='wangwu', age=23}]
    
  • 问题2解决方法

方法1:Student类实现Comparable接口,重写compareTo方法

public class Student implements Comparable<Student> {
    @Override
    public int compareTo(Student other) {
        return this.name.compareTo(other.name);
    }
}
运行结果:
HashSet的结果:
	[Student{name='lisi', age=23}, Student{name='zhangsan', age=20}, Student{name='wangwu', age=23}]
    
LinkedHashSet的结果:
	[Student{name='zhangsan', age=20}, Student{name='lisi', age=23}, Student{name='wangwu', age=23}]
    
TreeSet的结果:
	[Student{name='lisi', age=23}, Student{name='wangwu', age=23}, Student{name='zhangsan', age=20}]

Process finished with exit code 0

方法2:自定义外部比较器

有自定义的外部比较器以外部比较器为准,没有外部比较器的走内部比较器

按年龄升序,姓名降序排列

方法三:匿名内部类

package com.zhang.setdemo;

import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;

public class SetDemo03 {
    public static void main(String[] args) {
        //匿名内部类,年龄升序,姓名升序
        Comparator com = new Comparator<Student>() {
            @Override
            public int compare(Student stu1, Student stu2) {
                if (stu1.getAge() < stu2.getAge()) {
                    return -1;
                } else if (stu1.getAge() > stu2.getAge()) {
                    return 1;
                } else {
                    return stu1.getName().compareTo(stu2.getName());
                }
            }
        };
        Set<Student> set3 = new TreeSet(com);
        Student stu111 = new Student("zhangsan", 20);
        Student stu222 = new Student("lisi", 23);
        Student stu333 = new Student("wangwu", 23);
        Student stu444 = new Student("zhangsan", 20);
        set3.add(stu111);
        set3.add(stu222);
        set3.add(stu333);
        set3.add(stu444);
        System.out.println(set3);
    }
}

执行结果:
[Student{name='zhangsan', age=20}, Student{name='lisi', age=23}, Student{name='wangwu', age=23}]

Process finished with exit code 0

方法四:拉姆达表达式

package com.zhang.setdemo;

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

public class SetDemo04 {
    public static void main(String[] args) {
        //拉姆达表达式
        Set<Student> set3 = new TreeSet<Student>((Student stu1, Student stu2) -> {
            if (stu1.getAge() < stu2.getAge()) {
                return -1;
            } else if (stu1.getAge() > stu2.getAge()) {
                return 1;
            } else {
                return stu1.getName().compareTo(stu2.getName());
            }
        });
        Student stu111 = new Student("zhangsan", 20);
        Student stu222 = new Student("lisi", 23);
        Student stu333 = new Student("wangwu", 23);
        Student stu444 = new Student("zhangsan", 20);
        set3.add(stu111);
        set3.add(stu222);
        set3.add(stu333);
        set3.add(stu444);
        System.out.println(set3);
    }
}

方法五:拉姆达表达式一条语句的用法

package com.zhang.setdemo;

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

public class SetDemo05 {
    public static void main(String[] args) {
        //拉姆达表达式
        Set<Student> set3 = new TreeSet<Student>((stu1, stu2) -> stu1.getName().compareTo(stu2.getName()));
        Student stu111 = new Student("zhangsan", 20);
        Student stu222 = new Student("lisi", 23);
        Student stu333 = new Student("wangwu", 23);
        Student stu444 = new Student("zhangsan", 20);
        set3.add(stu111);
        set3.add(stu222);
        set3.add(stu333);
        set3.add(stu444);
        System.out.println(set3);
    }
}

执行结果:
[Student{name='lisi', age=23}, Student{name='wangwu', age=23}, Student{name='zhangsan', age=20}]

Process finished with exit code 0
posted @ 2021-07-24 17:47  wlbsm  阅读(43)  评论(0编辑  收藏  举报