java学习day13---Set

Set

子类有有HashSet,TreeSet,LinkedHashSet

特点,无序(指存取顺序),元素不可重复

存储基本数据类型时,已经默认重写的hashCode方法和equals方法,比较的是内容,所以不会存入内容相同得到元素

import java.util.HashSet;

public class SetDemo2 {
    public static void main(String[] args) {
        //Set集合的特点:元素无序,且唯一
        HashSet<Integer> hashSet = new HashSet<>();
        hashSet.add(100);
        hashSet.add(20);
        hashSet.add(30);
        hashSet.add(5);
        hashSet.add(60);
        hashSet.add(20);
        hashSet.add(30);
        hashSet.add(20);
        hashSet.add(30);

        //遍历
        for(Integer num:hashSet){
            System.out.println(num);
        }
    }
}

存储引用数据类型时(以Student类为案例),发现存入几个相同名字和年龄的对象,仍然可以重复,这是因为add方法底层调用的是hashCode方法和equals方法,默认比较的是地址值,而引用类型存储地址不同,因此可以存入,所以实际当中,我们应该重写Student类的hashCode方法和equals方法,满足需求


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

    @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 SetDemo3 {
    public static void main(String[] args) {
        Student s1 = new Student("王菲", 30);
        Student s2 = new Student("林俊杰", 30);
        Student s3 = new Student("周杰伦", 40);
        Student s4 = new Student("王菲", 20);
        Student s5 = new Student("陈奕迅", 18);
        Student s6 = new Student("林俊杰", 30);
        Student s7 = new Student("陈奕迅", 18);
        HashSet<Student> students = new HashSet<>();
 
        students.add(s1);
        students.add(s2);
        students.add(s3);
        students.add(s4);
        students.add(s5);
        students.add(s6);
        students.add(s7);
      
        System.out.println(students);
    }
}

 

1.HashSet

底层:数据结构是哈希表,线程不安全,效率高,允许存储null,具有数组和链表的特点

通过构造方法可以去除重复元素

import java.util.ArrayList;
import java.util.HashSet;

public class HashSetDemo3 {
    public static void main(String[] args) {
        ArrayList<Integer> integers = new ArrayList<>();
        integers.add(10);
        integers.add(10);
        integers.add(10);
        integers.add(10);
        integers.add(20);
        integers.add(20);
        //HashSet通过构造方法去除List集合中的重复元素
        HashSet<Integer> integers = new HashSet<>(integers);
        System.out.println(integers);
    }
}

2.LinkedHashSet

底层数据结构是链表和哈希表,所以元素有序,不可重复(要重写方法),线程不安全,效率高

import java.util.LinkedHashSet;

public class LinkedHashSetDemo {

    public static void main(String[] args) {
        //LinkedHashSet 元素有序且唯一
        LinkedHashSet<Integer> linkedHashSet = new LinkedHashSet<>();
        linkedHashSet.add(10);
        linkedHashSet.add(10);
        linkedHashSet.add(10);
        linkedHashSet.add(20);
        linkedHashSet.add(30);
        linkedHashSet.add(40);
        
        for(Integer num:linkedHashSet){
            System.out.println(num);
        }
    }
}

3.TreeSet

底层:数据结构是二叉树(红黑树)

特点:元素唯一且能对元素进行排序(元素值大小)

TreeSet对元素排序有两种方式:选择哪一种根据使用的构造方法决定

a.如果使用的是空参构造,则采用自然排序,要求:元素必须实现一个接口Comparable接口,并重写里面的compare方法,根据该方法的返回值来决定元素的排列顺序,而基本数据类型(String,Integer)已经默认实现重写

案例:按照学生年龄进行排序,如果年龄相同,则比较名字

import java.util.Objects;

public class Student implements Comparable<Student> {
    private String name;
    private int age;

    无参构造
    ...
    ...
    ...
    重写HashCode方法

    //根据此排序方法的返回值来决定元素的排列顺序
    @Override
    public int compareTo(Student s) {
        //根据年龄的大小去比较
        int r = this.age - s.age;
        //年龄一样并不能说明是同一个对象,我们还得比较姓名是否一样
        //boolean equals = this.name.equals(s.name);
        int r2 = r == 0 ? this.name.compareTo(s.name) : r;
        return -r2; //根据此方法的返回值的正负以及0来决定元素的排列顺序以及保证元素的唯一性
    }
}



import java.util.TreeSet;

public class TreeSet {
    public static void main(String[] args) {

        Student stu1 = new Student("lucy", 20);
        Student stu2 = new Student("jacker", 21);
        Student stu3 = new Student("marry", 22);
        Student stu4 = new Student("whitera", 19);
        Student stu5 = new Student("brown", 18);
        Student stu6 = new Student("lucy", 21);
        
        TreeSet<Student> students = new TreeSet<>();

        students.add(s1);
        students.add(s2);
        students.add(s3);
        students.add(s4);
        students.add(s5);
        students.add(s6);

        //遍历
        for(Student student:students){
            System.out.println(student.getName()+"==="+student.getAge());
        }
    }
}
        

    

b.如果使用的是有参构造,则采用比较器排序,实现Comparator接口,重写compare方法

步骤和无参构造是一样的,不过也可以使用匿名内部类的方式

匿名内部类的演示案例:(当然,你也可以选择重新创建一个类实现接口然后重写方法)

Class Student {
        Private String name;
        Private int age;
        ……

}

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

public class TreeSetDemo2 {
    public static void main(String[] args) {

        Student stu1 = new Student("lucy", 20);
        Student stu2 = new Student("jacker", 21);
        Student stu3 = new Student("marry", 22);
        Student stu4 = new Student("whitera", 19);
        Student stu5 = new Student("brown", 18);
        Student stu6 = new Student("lucy", 21);

        //通过内明内部类传一个比较器
        TreeSet<Student> students = new TreeSet<>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                int result = o1.getAge() - o2.getAge();
                int lastResult = result == 0 ? o1.getName().compareTo(o2.getName()) : result;
                return lastResult;
            }
        });

        students.add(stu1);
        students.add(stu2);
        students.add(stu3);
        students.add(stu4);
        students.add(stu5);
        students.add(stu6);

        for(Student s : students) {
            System.out.println(s.getName() + "---" +s.getAge());
        }
    }
}

例题:

键盘录入三个学生信息(姓名,语文成绩,数学成绩,英语成绩),并在控制台输出总成绩,按从高到低的形式

import java.util.Objects;

public class Student {
    private String name;
    private double Chinese;
    private double math;
    private double English;

    无参有参构造
    ...
    ...
    重写toString方法

    public double allScore(){
        return this.Chinese + this.math + this.English;
    }
}



import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;

public class Test {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        TreeSet<Student> students = new TreeSet<>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                int score = (int) (o1.allScore() - o2.allScore());

                return -score;
            }
        });
        for(int i = 1; i <= 3; i++) {
            System.out.print("请输入第" + i +"个学生姓名:");
            String name = scanner.next();
            System.out.print("请输入" + name +"的语文成绩:");
            double ChineseScore = scanner.nextDouble();
            System.out.print("请输入" + name +"的数学成绩:");
            double mathScore = scanner.nextDouble();
            System.out.print("请输入" + name +"的英语成绩:");
            double EnglishScore = scanner.nextDouble();

            Student s = new Student(name, ChineseScore, mathScore, EnglishScore);
            students.add(s);
        }
        System.out.println("姓名" + "---" + "语文" + "---" + "数学" + "---" + "英语" + "---" + "总分" );
        for(Student stu: students) {
            System.out.println(stu.getName() + "---" + stu.getChinese() + "---" + stu.getMath()
                    +"---" + stu.getEnglish() + "---" + stu.allScore());
        }
    }
}

 

 

 

 

 

猜你喜欢

转载自blog.csdn.net/szy2333/article/details/81392946