• Java学习笔记(十九)


    在完成对C语言的学习后,我最近开始了对C++和Java的学习,目前跟着视频学习了一些语法,也跟着敲了一些代码,有了一定的掌握程度。现在将跟着视频做的笔记进行整理。本篇博客是整理Java知识点的第十九篇博客。

    本篇博客介绍了Java的Set集合。

    本系列博客所有Java代码都使用IntelliJ IDEA编译运行,版本为2022.1。所用JDK版本为JDK11

    目录

    Set集合

    Set集合概述和特点

    哈希值

    HashSet集合概述和特点

    HashSet集合存储学生对象并遍历

    LinkedHashSet集合概述和特点

    TreeSet集合概述和特点

    Comparable

    Comparator

    成绩排序

    不重复的随机数


    Set集合

    Set集合概述和特点

    Set集合不包含重复元素,没有带索引的方法,因此不能用普通for循环遍历。

    可以通过HashSet实现Set,需要导包,import java.util.HashSet

    HashSet对集合的迭代顺序不保证。

    1. import java.util.Set;
    2. import java.util.HashSet;
    3. public class settest1 {
    4. public static void main(String[] args) {
    5. Set test = new HashSet();
    6. test.add("Hello");
    7. test.add("Java");
    8. test.add("This is ");
    9. test.add("set");
    10. test.add("Java");
    11. for(String s:test){
    12. System.out.println(s);
    13. }
    14. }
    15. }

    程序创建了一个HashSet集合,并使用增强for循环进行遍历。程序的输出是:

    Java
    set
    Hello
    This is 
    顺序与加入集合的顺序不一样。

    哈希值

    哈希值,是JDK根据对象的地址或数字算出的int类型的数值。

    Object类有一个方法可以获取对象的哈希值,即

    public int hashCode(),返回对象的哈希值

    同一个对象多次调用hashCode方法,返回的值相同。默认情况下不同对象哈希值不同。重写hashCode方法可以实现不同对象哈希值相同。

    1. public class student {
    2. private String name;
    3. private int age;
    4. public student(){}
    5. public student(String name,int age) {
    6. this.name = name;
    7. this.age = age;
    8. }
    9. public void setname(String name){
    10. this.name = name;
    11. }
    12. public String getname(){
    13. return name;
    14. }
    15. public void setage(int age){
    16. this.age = age;
    17. }
    18. public int getage(){
    19. return age;
    20. }
    21. }

    这是下面出现的学生类。

    1. public class hashcode {
    2. public static void main(String[] args) {
    3. student s1 = new student("Opal", 26);
    4. student s2 = new student("Olga", 20);
    5. System.out.println(s1.hashCode());
    6. System.out.println(s2.hashCode());
    7. System.out.println("hello".hashCode());
    8. System.out.println("haha".hashCode());
    9. System.out.println("hehe".hashCode());
    10. System.out.println(s1.hashCode());
    11. System.out.println(s2.hashCode());
    12. }
    13. }

    这段程序获取对象的哈希值并输出。程序的输出是:

    1784662007
    997110508
    99162322
    3194802
    3198650
    1784662007
    997110508

    HashSet集合概述和特点

    HashSet的底层数据结构是哈希表,HashSet对集合的迭代顺序不作任何保证,不能用普通for循环进行遍历。不包含重复元素。

    HashSet进行添加时,首先调用对象的hashCode方法获取对象的哈希值,根据哈希值计算出存储位置,该位置没有元素就将元素存入该位置。如果有元素,就遍历该位置所有元素,和新存入的元素比较哈希值,都不相同就将元素存入该位置。有相同就调用equals方法比较对象内容是否相等,结果为false就将元素存入该位置,否则表明元素重复,不进行存储。

    1. import java.util.Set;
    2. import java.util.HashSet;
    3. public class settest2 {
    4. public static void main(String[] args){
    5. Set test = new HashSet();
    6. test.add("Jebi");
    7. test.add("Mangkhut");
    8. test.add("Kong-rey");
    9. test.add("Yutu");
    10. for(String s:test){
    11. System.out.println(s);
    12. }
    13. }
    14. }

    程序创建了一个HashSet集合,并使用增强for循环进行输出。程序的输出是:

    Mangkhut
    Jebi
    Kong-rey
    Yutu

    HashSet集合存储学生对象并遍历

    1. import java.util.Objects;
    2. public class hashsetstudent {
    3. private String name;
    4. private int age;
    5. public hashsetstudent() {
    6. }
    7. public hashsetstudent(String name,int age){
    8. this.name = name;
    9. this.age = age;
    10. }
    11. public void setname(String name){
    12. this.name = name;
    13. }
    14. public String getname(){
    15. return name;
    16. }
    17. public void setage(int age){
    18. this.age = age;
    19. }
    20. public int getage(){
    21. return age;
    22. }
    23. @Override
    24. public boolean equals(Object o) {
    25. if (this == o) return true;
    26. if (o == null || getClass() != o.getClass()) return false;
    27. hashsetstudent that = (hashsetstudent) o;
    28. return age == that.age && name.equals(that.name);
    29. }
    30. @Override
    31. public int hashCode() {
    32. return Objects.hash(name, age);
    33. }
    34. }

    这是对应的学生类,并重写了equals方法和hashCode方法。

    1. import java.util.Set;
    2. import java.util.HashSet;
    3. public class hashsetstudenttest {
    4. public static void main(String[] args){
    5. Set test = new HashSet();
    6. hashsetstudent hss1 = new hashsetstudent("Olaf",25);
    7. hashsetstudent hss2 = new hashsetstudent("Odile",17);
    8. hashsetstudent hss3 = new hashsetstudent("Otis",24);
    9. hashsetstudent hss4 = new hashsetstudent("Olaf",25);
    10. test.add(hss1);
    11. test.add(hss2);
    12. test.add(hss3);
    13. test.add(hss4);
    14. for(hashsetstudent hss:test){
    15. System.out.println("The name is " + hss.getname());
    16. System.out.println("The age is " + hss.getage());
    17. }
    18. }
    19. }

    这段代码创建了几个hashsetstudent类对象,并放入集合后进行遍历输出。程序的输出是:

    The name is Olaf
    The age is 25
    The name is Odile
    The age is 17
    The name is Otis
    The age is 24

    LinkedHashSet集合概述和特点

    LinkedHashSet是用哈希表和链表实现的Set接口,具有可预测的迭代次序。元素的存储和取出的顺序一致,并且没有重复元素。

    使用LinkedHashSet需要导包,import java.util.LinkedHashSet

    1. import java.util.Set;
    2. import java.util.LinkedHashSet;
    3. public class linkedhashsettest {
    4. public static void main(String[] args){
    5. Set test = new LinkedHashSet();
    6. test.add("Hello");
    7. test.add("world");
    8. test.add("Java");
    9. for(String s:test){
    10. System.out.println(s);
    11. }
    12. }
    13. }

    程序创建了一个LinkedHashSet,并进行遍历输出。程序的输出是:

    Hello
    world
    Java

    TreeSet集合概述和特点

    TreeSet集合的元素按照一定的规则排序。具体排序方法取决于构造方法。

    TreeSet()按照默认排序进行排序。

    TreeSet(Comparator comparator)根据指定的比较器进行排序。

    使用TreeSet要进行导包,import java.util.TreeSet

    TreeSet不能用普通for循环进行遍历,不包含重复元素。

    集合存放基本数据类型时,应该放包装类(如用Integer而不是int)。

    1. import java.util.Set;
    2. import java.util.TreeSet;
    3. public class treesettest {
    4. public static void main(String[] args){
    5. Set test = new TreeSet();
    6. test.add(10);
    7. test.add(15);
    8. test.add(20);
    9. test.add(5);
    10. test.add(25);
    11. for(int i:test){
    12. System.out.println(i);
    13. }
    14. }
    15. }

    程序创建了一个TreeSet集合test,并加入五个Integer,随后进行遍历输出。程序的输出是:

    5
    10
    15
    20
    25
    可见默认是从小到大排序。

    Comparable

    用TreeSet存储自定义对象时,无参构造方法使用自然排序。自然排序,就是让元素所属的类实现Comparable接口,并重写CompareTo方法。

    1. public class comparablestudent implements Comparable{
    2. private String name;
    3. private int age;
    4. public comparablestudent(){
    5. }
    6. public comparablestudent(String name,int age){
    7. this.name = name;
    8. this.age = age;
    9. }
    10. public void setname(String name){
    11. this.name = name;
    12. }
    13. public String getname(){
    14. return name;
    15. }
    16. public void setage(int age){
    17. this.age = age;
    18. }
    19. public int getage(){
    20. return age;
    21. }
    22. public int compareTo(comparablestudent cs) {
    23. if(this.getage() != cs.getage()){
    24. return this.getage() - cs.getage();
    25. }else{
    26. return this.getname().compareTo(cs.getname());
    27. }
    28. }
    29. }

    这是学生类,重写了compareTo方法,将当前对象和参数进行比较,先比较年龄,年龄相等再比较姓名。并将结果返回。

    1. import java.util.Set;
    2. import java.util.TreeSet;
    3. public class comparabletest {
    4. public static void main(String[] args){
    5. Set test = new TreeSet();
    6. comparablestudent cs1 = new comparablestudent("Peter",19);
    7. comparablestudent cs2 = new comparablestudent("Patricia",19);
    8. comparablestudent cs3 = new comparablestudent("Rene",14);
    9. comparablestudent cs4 = new comparablestudent("Marty",25);
    10. test.add(cs1);
    11. test.add(cs2);
    12. test.add(cs3);
    13. test.add(cs4);
    14. for(comparablestudent cs:test){
    15. System.out.println("The name is " + cs.getname());
    16. System.out.println("The age is " + cs.getage());
    17. }
    18. }
    19. }

    程序创建了comparablestudent类的对象,并加入TreeSet集合,随后进行遍历输出。程序的输出是:

    The name is Rene
    The age is 14
    The name is Patricia
    The age is 19
    The name is Peter
    The age is 19
    The name is Marty
    The age is 25

    Comparator

    用TreeSet存储自定义对象时,带参构造方法使用比较器排序对元素进行排序。需要让集合构造方法接收Comparator的实现类对象,并重写compare(T o1,T o2)方法。

    使用比较器排序需要导包,import java.util.Comparator

    1. public class comparatorstudent {
    2. private String name;
    3. private int age;
    4. public comparatorstudent(){
    5. }
    6. public comparatorstudent(String name,int age){
    7. this.name = name;
    8. this.age = age;
    9. }
    10. public void setname(String name){
    11. this.name = name;
    12. }
    13. public String getname(){
    14. return name;
    15. }
    16. public void setage(int age){
    17. this.age = age;
    18. }
    19. public int getage(){
    20. return age;
    21. }
    22. }

    这是学生类。

    1. import java.util.Set;
    2. import java.util.TreeSet;
    3. import java.util.Comparator;
    4. public class comparatortest {
    5. public static void main(String[] args){
    6. Set test = new TreeSet(
    7. new Comparator(){
    8. public int compare(comparatorstudent csa,comparatorstudent csb){
    9. if(csa.getage() != csb.getage()){
    10. return csa.getage() - csb.getage();
    11. }else{
    12. return csa.getname().compareTo(csb.getname());
    13. }
    14. }
    15. }
    16. );
    17. comparatorstudent cs1 = new comparatorstudent("Peter",19);
    18. comparatorstudent cs2 = new comparatorstudent("Patricia",19);
    19. comparatorstudent cs3 = new comparatorstudent("Rene",14);
    20. comparatorstudent cs4 = new comparatorstudent("Marty",25);
    21. test.add(cs1);
    22. test.add(cs2);
    23. test.add(cs3);
    24. test.add(cs4);
    25. for(comparatorstudent cs:test){
    26. System.out.println("The name is " + cs.getname());
    27. System.out.println("The age is " + cs.getage());
    28. }
    29. }
    30. }

    程序的TreeSet使用了一个比较器,用匿名内部类,重写了compare方法,先比较年龄再比较姓名。随后向其中加入四个comparatorstudent对象并进行遍历输出。

    程序的输出是:

    The name is Rene
    The age is 14
    The name is Patricia
    The age is 19
    The name is Peter
    The age is 19
    The name is Marty
    The age is 25

    成绩排序

    1. public class studentscore {
    2. private String name;
    3. private int ascore;
    4. private int bscore;
    5. public studentscore(){}
    6. public studentscore(String name,int ascore,int bscore){
    7. this.name = name;
    8. this.ascore = ascore;
    9. this.bscore = bscore;
    10. }
    11. public void setname(String name){
    12. this.name = name;
    13. }
    14. public String getname(){
    15. return name;
    16. }
    17. public void setascore(int ascore){
    18. this.ascore = ascore;
    19. }
    20. public int getascore(){
    21. return ascore;
    22. }
    23. public void setbscore(int bscore){
    24. this.bscore = bscore;
    25. }
    26. public int getbscore(){
    27. return bscore;
    28. }
    29. public int getscore(){
    30. return ascore + bscore;
    31. }
    32. }

    studentscore类的成员变量ascore和bscore代表英语和数学的分数,getscore成员方法返回ascore和bscore的和。

    1. import java.util.Set;
    2. import java.util.TreeSet;
    3. import java.util.Comparator;
    4. public class studentscoretest {
    5. public static void main(String[] args) {
    6. Set test = new TreeSet(
    7. new Comparator() {
    8. public int compare(studentscore a, studentscore b) {
    9. if (a.getscore() != b.getscore()) {
    10. return b.getscore() - a.getscore();
    11. } else {
    12. return b.getname().compareTo(a.getname());
    13. }
    14. }
    15. }
    16. );
    17. studentscore sc1 = new studentscore("Nicholas",75,84);
    18. studentscore sc2 = new studentscore("Norbert",65,56);
    19. studentscore sc3 = new studentscore("Narda",86,73);
    20. studentscore sc4 = new studentscore("Nestor",90,97);
    21. studentscore sc5 = new studentscore("Nadine",78,84);
    22. studentscore sc6 = new studentscore("Norman",85,93);
    23. test.add(sc1);
    24. test.add(sc2);
    25. test.add(sc3);
    26. test.add(sc4);
    27. test.add(sc5);
    28. test.add(sc6);
    29. for(studentscore sc:test){
    30. System.out.println("The name is " + sc.getname());
    31. System.out.println("The score of English is " + sc.getascore());
    32. System.out.println("The score of Math is " + sc.getbscore());
    33. }
    34. }
    35. }

    这段代码创建了一个TreeSet,并用比较器规定排序规则是先比较总分后比较姓名,进行降序排序。随后加入几个studentscore类对象并进行遍历输出。程序的输出是:

    The name is Nestor
    The score of English is 90
    The score of Math is 97
    The name is Norman
    The score of English is 85
    The score of Math is 93
    The name is Nadine
    The score of English is 78
    The score of Math is 84
    The name is Nicholas
    The score of English is 75
    The score of Math is 84
    The name is Narda
    The score of English is 86
    The score of Math is 73
    The name is Norbert
    The score of English is 65
    The score of Math is 56

    不重复的随机数

    利用Set的成员不能重复的特性,可以得到不重复元素的集合。

    1. import java.util.Random;
    2. import java.util.Set;
    3. import java.util.HashSet;
    4. public class randomnumber {
    5. public static void main(String[] args){
    6. Random r = new Random();
    7. int number;
    8. Set test = new HashSet();
    9. while(test.size()<10){
    10. number = r.nextInt(20) + 1;
    11. test.add(number);
    12. }
    13. for(int num:test){
    14. System.out.println(num);
    15. }
    16. }
    17. }

    这段代码创建了一个HashSet集合test,存储Integer类型数据。随后进入循环,要求元素个数达到10个后退出。循环内每次生成一个1-20的随机数,随后加入集合。由于Set元素的特性,出现相同元素时个数不变,因此得到10个不相同的数。最后遍历输出。一次运行的结果是(用空格代替换行):

    16 3 4 20 5 9 10 11 14 15

  • 相关阅读:
    矩阵分析与应用
    Django缓存
    prometheus + grafana进行服务器资源监控
    LeetCode第7题:整数反转
    TypeScript教程-2022
    (210)Verilog HDL:设计一个电路之Rule 110
    英国Top20名校更偏爱IB申请党?
    【手把手带你刷好题】Java刷题记录 15——>>20
    vue3中手写组合API shallowReactive 与 reactive
    【算法leetcode】1051. 高度检查器(rust和go)
  • 原文地址:https://blog.csdn.net/m0_71007572/article/details/126373161