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对集合的迭代顺序不保证。

import java.util.Set;
import java.util.HashSet;
public class settest1 {
    public static void main(String[] args) {
        Set<String> test = new HashSet();
        test.add("Hello");
        test.add("Java");
        test.add("This is ");
        test.add("set");
        test.add("Java");

        for(String s:test){
            System.out.println(s);
        }
    }
}

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

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

哈希值

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

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

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

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

public class student {
    private String name;
    private int age;
    public student(){}
    public student(String name,int age) {
        this.name = name;
        this.age = age;
    }

    public void setname(String name){
        this.name = name;
    }
    public String getname(){
        return name;
    }
    public void setage(int age){
        this.age = age;
    }
    public int getage(){
        return age;
    }
}

这是下面出现的学生类。

public class hashcode {
    public static void main(String[] args) {
        student s1 = new student("Opal", 26);
        student s2 = new student("Olga", 20);
        System.out.println(s1.hashCode());
        System.out.println(s2.hashCode());

        System.out.println("hello".hashCode());
        System.out.println("haha".hashCode());
        System.out.println("hehe".hashCode());

        System.out.println(s1.hashCode());
        System.out.println(s2.hashCode());
    }
}

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

1784662007
997110508
99162322
3194802
3198650
1784662007
997110508

HashSet集合概述和特点

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

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

import java.util.Set;
import java.util.HashSet;
public class settest2 {
    public static void main(String[] args){
        Set<String> test = new HashSet<String>();
        test.add("Jebi");
        test.add("Mangkhut");
        test.add("Kong-rey");
        test.add("Yutu");
        for(String s:test){
            System.out.println(s);
        }
    }
}

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

Mangkhut
Jebi
Kong-rey
Yutu

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

import java.util.Objects;

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

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

    public void setname(String name){
        this.name = name;
    }
    public String getname(){
        return name;
    }

    public void setage(int age){
        this.age = age;
    }
    public int getage(){
        return age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        hashsetstudent that = (hashsetstudent) o;
        return age == that.age && name.equals(that.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}

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

import java.util.Set;
import java.util.HashSet;
public class hashsetstudenttest {
    public static void main(String[] args){
        Set<hashsetstudent> test = new HashSet<hashsetstudent>();
        hashsetstudent hss1 = new hashsetstudent("Olaf",25);
        hashsetstudent hss2 = new hashsetstudent("Odile",17);
        hashsetstudent hss3 = new hashsetstudent("Otis",24);
        hashsetstudent hss4 = new hashsetstudent("Olaf",25);

        test.add(hss1);
        test.add(hss2);
        test.add(hss3);
        test.add(hss4);

        for(hashsetstudent hss:test){
            System.out.println("The name is " + hss.getname());
            System.out.println("The age is " + hss.getage());
        }
    }
}

这段代码创建了几个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

import java.util.Set;
import java.util.LinkedHashSet;
public class linkedhashsettest {
    public static void main(String[] args){
        Set<String> test = new LinkedHashSet<String>();
        test.add("Hello");
        test.add("world");
        test.add("Java");

        for(String s:test){
            System.out.println(s);
        }
    }
}

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

Hello
world
Java

TreeSet集合概述和特点

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

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

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

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

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

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

import java.util.Set;
import java.util.TreeSet;
public class treesettest {
    public static void main(String[] args){
        Set<Integer> test = new TreeSet<Integer>();
        test.add(10);
        test.add(15);
        test.add(20);
        test.add(5);
        test.add(25);

        for(int i:test){
            System.out.println(i);
        }
    }
}

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

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

Comparable

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

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

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

    public void setname(String name){
        this.name = name;
    }
    public String getname(){
        return name;
    }
    public void setage(int age){
        this.age = age;
    }
    public int getage(){
        return age;
    }

    public int compareTo(comparablestudent cs) {
        if(this.getage() != cs.getage()){
            return this.getage() - cs.getage();
        }else{
            return this.getname().compareTo(cs.getname());
        }
    }
}

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

import java.util.Set;
import java.util.TreeSet;
public class comparabletest {
    public static void main(String[] args){
        Set<comparablestudent> test = new TreeSet<comparablestudent>();
        comparablestudent cs1 = new comparablestudent("Peter",19);
        comparablestudent cs2 = new comparablestudent("Patricia",19);
        comparablestudent cs3 = new comparablestudent("Rene",14);
        comparablestudent cs4 = new comparablestudent("Marty",25);
        test.add(cs1);
        test.add(cs2);
        test.add(cs3);
        test.add(cs4);

        for(comparablestudent cs:test){
            System.out.println("The name is " + cs.getname());
            System.out.println("The age is " + cs.getage());
        }
    }
}

程序创建了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

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

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

    public void setname(String name){
        this.name = name;
    }
    public String getname(){
        return name;
    }
    public void setage(int age){
        this.age = age;
    }
    public int getage(){
        return age;
    }
}

这是学生类。

import java.util.Set;
import java.util.TreeSet;
import java.util.Comparator;
public class comparatortest {
    public static void main(String[] args){
        Set<comparatorstudent> test = new TreeSet<comparatorstudent>(
                new Comparator<comparatorstudent>(){
                    public int compare(comparatorstudent csa,comparatorstudent csb){
                        if(csa.getage() != csb.getage()){
                            return csa.getage() - csb.getage();
                        }else{
                            return csa.getname().compareTo(csb.getname());
                        }
                    }
                }
        );

        comparatorstudent cs1 = new comparatorstudent("Peter",19);
        comparatorstudent cs2 = new comparatorstudent("Patricia",19);
        comparatorstudent cs3 = new comparatorstudent("Rene",14);
        comparatorstudent cs4 = new comparatorstudent("Marty",25);
        test.add(cs1);
        test.add(cs2);
        test.add(cs3);
        test.add(cs4);

        for(comparatorstudent cs:test){
            System.out.println("The name is " + cs.getname());
            System.out.println("The age is " + cs.getage());
        }
    }
}

程序的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

成绩排序

public class studentscore {
    private String name;
    private int ascore;
    private int bscore;

    public studentscore(){}
    public studentscore(String name,int ascore,int bscore){
        this.name = name;
        this.ascore = ascore;
        this.bscore = bscore;
    }

    public void setname(String name){
        this.name = name;
    }
    public String getname(){
        return name;
    }

    public void setascore(int ascore){
       this.ascore = ascore;
    }
    public int getascore(){
        return ascore;
    }

    public void setbscore(int bscore){
        this.bscore = bscore;
    }
    public int getbscore(){
        return bscore;
    }

    public int getscore(){
        return ascore + bscore;
    }
}

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

import java.util.Set;
import java.util.TreeSet;
import java.util.Comparator;
public class studentscoretest {
    public static void main(String[] args) {
        Set<studentscore> test = new TreeSet<studentscore>(
                new Comparator<studentscore>() {
                    public int compare(studentscore a, studentscore b) {
                        if (a.getscore() != b.getscore()) {
                            return b.getscore() - a.getscore();
                        } else {
                            return b.getname().compareTo(a.getname());
                        }
                    }
                }
        );

        studentscore sc1 = new studentscore("Nicholas",75,84);
        studentscore sc2 = new studentscore("Norbert",65,56);
        studentscore sc3 = new studentscore("Narda",86,73);
        studentscore sc4 = new studentscore("Nestor",90,97);
        studentscore sc5 = new studentscore("Nadine",78,84);
        studentscore sc6 = new studentscore("Norman",85,93);

        test.add(sc1);
        test.add(sc2);
        test.add(sc3);
        test.add(sc4);
        test.add(sc5);
        test.add(sc6);

        for(studentscore sc:test){
            System.out.println("The name is " + sc.getname());
            System.out.println("The score of English is " + sc.getascore());
            System.out.println("The score of Math is " + sc.getbscore());
        }
    }
}

这段代码创建了一个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的成员不能重复的特性,可以得到不重复元素的集合。

import java.util.Random;
import java.util.Set;
import java.util.HashSet;
public class randomnumber {
    public static void main(String[] args){
        Random r = new Random();
        int number;

        Set<Integer> test = new HashSet<Integer>();
        while(test.size()<10){
            number = r.nextInt(20) + 1;
            test.add(number);
        }

        for(int num:test){
            System.out.println(num);
        }
    }
}

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

16 3 4 20 5 9 10 11 14 15

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值