4、Set集合——HashSet、TreeSet(Comparable、Comparator)

小不點_發表於2020-11-13


1. Set集合特點

  • 不包含重複元素的集合
  • 沒有帶索引的方法,所以不能使用普通for迴圈遍歷

1.1 Set集合練習:儲存字串並遍歷

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

public class SetDemo {
    public static void main(String[] args) {
        //建立集合物件
        Set<String> set = new HashSet<String>();

        //新增元素
        set.add("hello");
        set.add("world");
        set.add("java");
        //不包含重複元素的集合
        set.add("world");

        //遍歷
        for(String s : set) {
            System.out.println(s);
        }

    }
}

2. 什麼是雜湊值

雜湊值:是JDK根據物件的地址或者字串或者數字算出來的int型別的數值

Object類中有一個方法可以獲取物件的雜湊值

  • public int hashCode​():返回物件的雜湊碼值

物件的雜湊值特點

  • 同一個物件多次呼叫hashCode()方法返回的雜湊值是相同的

  • 預設情況下,不同物件的雜湊值是不同的。而重寫hashCode()方法,可以實現讓不同物件的雜湊值相同

2.1 Hash練習:

/*
    雜湊值:
        是JDK根據物件的地址或者字串或者數字算出來的int型別的數值

    Object類中有一個方法可以獲取物件的雜湊值
        public int hashCode():返回物件的雜湊碼值
 */
public class HashDemo {
    public static void main(String[] args) {
        //建立學生物件
        Student s1 = new Student("林青霞",30);

        //同一個物件多次呼叫hashCode()方法返回的雜湊值是相同的
        System.out.println(s1.hashCode()); //1060830840
        System.out.println(s1.hashCode()); //1060830840
        System.out.println("--------");

        Student s2 = new Student("林青霞",30);

        //預設情況下,不同物件的雜湊值是不相同的
        //通過方法重寫,可以實現不同物件的雜湊值是相同的
        System.out.println(s2.hashCode()); //2137211482
        System.out.println("--------");

        System.out.println("hello".hashCode()); //99162322
        System.out.println("world".hashCode()); //113318802
        System.out.println("java".hashCode()); //3254818

        System.out.println("world".hashCode()); //113318802
        System.out.println("--------");

        System.out.println("重地".hashCode()); //1179395
        System.out.println("通話".hashCode()); //1179395


    }
}

3. HashSet集合概述和特點

  • 底層資料結構是雜湊表
  • 對集合的迭代順序不作任何保證,也就是說不保證儲存和取出的元素順序一致
  • 沒有帶索引的方法,所以不能使用普通for迴圈遍歷
  • 由於是Set集合,所以是不包含重複元素的集合

3.1 應用案例1:HashSet集合儲存學生物件並遍歷

需求:建立一個儲存學生物件的集合,儲存多個學生物件,使用程式實現在控制檯遍歷該集合
要求:學生物件的成員變數值相同,我們就認為是同一個物件
思路:

  1. 定義學生類
  2. 建立HashSet集合物件
  3. 建立學生物件
  4. 把學生新增到集合
  5. 遍歷集合(增強for)
  6. 在學生類中重寫兩個方法: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 boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Student student = (Student) o;

        if (age != student.age) return false;
        return name != null ? name.equals(student.name) : student.name == null;
    }

    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + age;
        return result;
    }
}

測試類:

import java.util.HashSet;

public class HashSetDemo02 {
    public static void main(String[] args) {
        //建立HashSet集合物件
        HashSet<Student> hs = new HashSet<Student>();

        //建立學生物件
        Student s1 = new Student("林青霞", 30);
        Student s2 = new Student("張曼玉", 35);
        Student s3 = new Student("王祖賢", 33);

        Student s4 = new Student("王祖賢", 33);

        //把學生新增到集合
        hs.add(s1);
        hs.add(s2);
        hs.add(s3);
        hs.add(s4);

        //遍歷集合(增強for)
        for (Student s : hs) {
            System.out.println(s.getName() + "," + s.getAge());
        }

    }
}

4. TreeSet集合概述和特點

  • 元素有序,這裡的順序不是指儲存和取出的順序,而是按照一定的規則進行排序,具體排序方式取決於構造方法
    TreeSet​():根據其元素的自然排序進行排序 TreeSet​(Comparator
    comparator):根據指定的比較器進行排序

  • 沒有帶索引的方法,所以不能使用普通for迴圈遍歷

  • 由於是Set集合,所以不包含重複元素的集合

4.1 TreeSet集合練習:儲存整數並遍歷

import java.util.TreeSet;

public class TreeSetDemo01 {
    public static void main(String[] args) {
        //建立集合物件
        TreeSet<Integer> ts = new TreeSet<Integer>();

        //新增元素
        ts.add(10);
        ts.add(40);
        ts.add(30);
        ts.add(50);
        ts.add(20);

        ts.add(30);

        //遍歷集合
        for(Integer i : ts) {
            System.out.println(i);
        }
    }
}

4.2 自然排序Comparable的使用

  • 用TreeSet集合儲存自定義物件,無參構造方法使用的是自然排序對元素進行排序的

  • 自然排序,就是讓元素所屬的類實現Comparable介面,重寫compareTo​(T o)方法

  • 重寫方法時,一定要注意排序規則必須按照要求的主要條件和次要條件來寫

Comparable的練習:

  • 儲存學生物件並遍歷,建立TreeSet集合使用無參構造方法

  • 要求:按照年齡從小到大排序,年齡相同時,按照姓名的字母順序排序

學生類:重寫compareTo​(T o)方法

public class Student implements Comparable<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 int compareTo(Student s) {
//        return 0;
//        return 1;
//        return -1;
        //按照年齡從小到大排序
       int num = this.age - s.age;
//        int num = s.age - this.age;
        //年齡相同時,按照姓名的字母順序排序
       int num2 = num==0?this.name.compareTo(s.name):num;
        return num2;
    }
}

測試類:

import java.util.TreeSet;

public class TreeSetDemo02 {
    public static void main(String[] args) {
        //建立集合物件
        TreeSet<Student> ts = new TreeSet<Student>();

        //建立學生物件
        Student s1 = new Student("xishi", 29);
        Student s2 = new Student("wangzhaojun", 28);
        Student s3 = new Student("diaochan", 30);
        Student s4 = new Student("yangyuhuan", 33);

        Student s5 = new Student("linqingxia",33);
        Student s6 = new Student("linqingxia",33);

        //把學生新增到集合
        ts.add(s1);
        ts.add(s2);
        ts.add(s3);
        ts.add(s4);
        ts.add(s5);
        ts.add(s6);

        //遍歷集合
        for (Student s : ts) {
            System.out.println(s.getName() + "," + s.getAge());
        }
    }
}

4.3 比較器排序Comparator的使用

  • 用TreeSet集合儲存自定義物件,帶參構造方法使用的是比較器排序對元素進行排序的

  • 比較器排序,就是讓集合構造方法接收Comparator的實現類物件,重寫compare​(T o1,T o2)方法

  • 重寫方法時,一定要注意排序規則必須按照要求的主要條件和次要條件來寫

Comparable的練習:

  • 儲存學生物件並遍歷,建立TreeSet集合使用帶參構造方法

  • 要求:按照年齡從小到大排序,年齡相同時,按照姓名的字母順序排序

學生類:

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

測試類:重寫compare​(T o1,T o2)方法

import java.util.Comparator;
import java.util.TreeSet;
public class TreeSetDemo {
    public static void main(String[] args) {
        //建立集合物件
        TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {
            @Override
            public int compare(Student s1, Student s2) {
                //this.age - s.age
                //s1,s2
                int num = s1.getAge() - s2.getAge();
                int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
                return num2;
            }
        });

        //建立學生物件
        Student s1 = new Student("xishi", 29);
        Student s2 = new Student("wangzhaojun", 28);
        Student s3 = new Student("diaochan", 30);
        Student s4 = new Student("yangyuhuan", 33);

        Student s5 = new Student("linqingxia",33);
        Student s6 = new Student("linqingxia",33);

        //把學生新增到集合
        ts.add(s1);
        ts.add(s2);
        ts.add(s3);
        ts.add(s4);
        ts.add(s5);
        ts.add(s6);

        //遍歷集合
        for (Student s : ts) {
            System.out.println(s.getName() + "," + s.getAge());
        }
    }
}

4.4 應用案例2:成績排序(通過比較器排序進行排序)

需求:用TreeSet集合儲存多個學生資訊(姓名,語文成績,數學成績),並遍歷該集合
要求:按照總分從高到低出現
思路:

  1. 定義學生類
  2. 建立TreeSet集合物件,通過比較器排序進行排序
  3. 建立學生物件
  4. 把學生物件新增到集合
  5. 遍歷集合

學生類:

public class Student {
    private String name;
    private int chinese;
    private int math;

    public Student() {
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getChinese() {
        return chinese;
    }

    public void setChinese(int chinese) {
        this.chinese = chinese;
    }

    public int getMath() {
        return math;
    }

    public void setMath(int math) {
        this.math = math;
    }

    public int getSum() {
        return this.chinese + this.math;
    }
}

測試類:

import java.util.Comparator;
import java.util.TreeSet;
public class TreeSetDemo {
    public static void main(String[] args) {
        //建立TreeSet集合物件,通過比較器排序進行排序
        TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {
            @Override
            public int compare(Student s1, Student s2) {
//                int num = (s2.getChinese()+s2.getMath())-(s1.getChinese()+s1.getMath());
                //主要條件
                int num = s2.getSum() - s1.getSum();
                //次要條件
                int num2 = num == 0 ? s1.getChinese() - s2.getChinese() : num;
                int num3 = num2 == 0 ? s1.getName().compareTo(s2.getName()) : num2;
                return num3;
            }
        });

        //建立學生物件
        Student s1 = new Student("林青霞", 98, 100);
        Student s2 = new Student("張曼玉", 95, 95);
        Student s3 = new Student("王祖賢", 100, 93);
        Student s4 = new Student("柳巖", 100, 97);
        Student s5 = new Student("風清揚", 98, 98);

        Student s6 = new Student("左冷禪", 97, 99);
//        Student s7 = new Student("左冷禪", 97, 99);
        Student s7 = new Student("趙雲", 97, 99);

        //把學生物件新增到集合
        ts.add(s1);
        ts.add(s2);
        ts.add(s3);
        ts.add(s4);
        ts.add(s5);
        ts.add(s6);
        ts.add(s7);

        //遍歷集合
        for (Student s : ts) {
            System.out.println(s.getName() + "," + s.getChinese() + "," + s.getMath() + "," + s.getSum());
        }
    }
}

相關文章