首页 > 其他分享 >HashSet以及TreeSet实现了哪些接口?有什么作用?

HashSet以及TreeSet实现了哪些接口?有什么作用?

时间:2023-04-23 12:55:43浏览次数:126  
标签:Comparable set HashSet 接口 Student new TreeSet

HashSet简介

HashSet是Java集合框架中非常常用的一种无序、不可重复的集合。它是通过哈希表来实现的,可以快速检索元素并消除重复。

泛型的作用

泛型可以帮助我们在编译时就发现类型错误,从而减少了运行时错误的发生。在使用HashSet时,我们通常会指定它的泛型类型为某个具体的类或接口。

假设我们定义一个Student类,并将其作为HashSet的泛型类型:

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

    // 省略构造函数和getter/setter方法
}

我们可以创建一个HashSet对象,并向其中添加多个Student对象:

Set<Student> set = new HashSet<>();
set.add(new Student("Tom", 18));
set.add(new Student("Lucy", 20));
set.add(new Student("John", 22));

为什么需要重写hashCode和equals方法

我们知道,HashSet是通过哈希表来实现的。当要往HashSet中添加某个元素时,HashSet会首先调用该元素的hashCode()方法,得到一个哈希值,然后根据这个哈希值寻找到对应的桶(哈希码)。如果该桶为空,说明该元素在HashSet中不存在,可以直接添加到该桶中。

但是,如果该桶已经存在其他元素,则需要调用这些元素的equals()方法来判断这些元素是否和要添加的元素重复。如果重复了,则无需再次添加,否则就将该元素添加到该桶中。这个过程就是HashSet中去重的过程。

那么问题来了:如何比较两个对象是否相等呢?在Java中,我们通常会重写hashCode()和equals()方法来进行比较。

在上面的代码中,我们并没有重写hashCode()和equals()方法。这样,当我们尝试将多个Student对象添加到HashSet中时,可能会出现重复的情况。

所以,我们需要针对具体的泛型类型,重写它们的hashCode()和equals()方法。这样才能确保HashSet中的元素不会重复,而是按照自己定义的相等规则进行比较。

以下是一个自定义Person类的例子:

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

    // 省略构造函数和getter/setter方法

    @Override
    public boolean equals(Object obj) {
        if (obj == null || !(obj instanceof Person)) {
            return false;
        }
        Person p = (Person)obj;
        return this.name.equals(p.getName()) && this.age == p.getAge();
    }

    @Override
    public int hashCode() {
        return 31 * name.hashCode() + age;
    }
}

在这个例子中,Person类的equals方法判断两个Person对象是否相等,它判断了name和age属性。而hashCode方法则使用了name和age属性的哈希码来计算元素的位置。

在实际开发中,我们可以根据具体的业务需求来定义equals()和hashCode()方法的实现。但一定要确保hashCode()方法的值能够尽量均匀地分布在整个Hash表中,不要让其出现哈希冲突,否则会影响HashSet的性能。

TreeSet的Comparable接口

Comparable接口的介绍

在Java中,如果我们想要对某个类的对象进行排序,可以让该类实现Comparable接口,并重写compareTo方法。Comparable接口的作用是指定一个类的自然顺序,即通过compareTo方法来定义该类的对象之间的大小关系。

Comparable接口只包含一个抽象方法:compareTo(Object obj),该方法接收一个Object对象作为参数,表示要比较的另一个对象。该方法返回一个int值,用于表示当前对象和另一个对象之间的大小关系,具体规则如下:

  • 如果当前对象小于目标对象,则返回负数;
  • 如果当前对象等于目标对象,则返回0;
  • 如果当前对象大于目标对象,则返回正数。

实现Comparable接口的两种方法

我们已经了解了Comparable接口的基本概念,接下来我们来看一下如何在TreeSet中使用该接口进行对象排序。实现Comparable接口的方式有两种:一种是在自定义对象中继承Comparable接口并重写compareTo方法,另一种是使用匿名函数重写compareTo方法。

第一种方式:在自定义对象中继承Comparable接口并重写compareTo方法

对于自定义的Student类,我们可以让它实现Comparable接口并重写compareTo方法。以下是一个例子:

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

    // 省略构造函数和getter/setter方法

    @Override
    public int compareTo(Student s) {
        if (this.age < s.getAge()) {
            return -1;
        } else if (this.age > s.getAge()) {
            return 1;
        }
        return 0;
    }
}

在这个例子中,我们让Student类实现了Comparable接口,并在compareTo()方法中,按照age属性进行排序。当需要对Student类的实例进行排序时,只需要将Student类的实例添加到TreeSet集合中即可:

Set<Student> set = new TreeSet<>();
set.add(new Student("Tom", 20));
set.add(new Student("Lucy", 18));
set.add(new Student("John", 22));

通过set的迭代器可以获取到有序的元素。

第二种方式:使用匿名函数重写compareTo方法

使用匿名函数重写compareTo方法可以让我们在不修改原代码的情况下,按照指定的条件进行排序,非常方便。以下是一个例子:

Set<Student> set = new TreeSet<>(new Comparator<Student>() {
    @Override
    public int compare(Student o1, Student o2) {
       return o1.getName().compareTo(o2.getName());
    }
});
set.add(new Student("Tom", 20));
set.add(new Student("Lucy", 18));
set.add(new Student("John", 22));

在这个例子中,我们使用了匿名函数来实现了Comparator接口,并在compare()方法中,按照name属性进行排序。

总结

HashSet和TreeSet是Java集合框架中最常用的两种集合类型。HashSet可以帮助我们去重和快速查找元素,而TreeSet则可以帮助我们将元素排序。当我们使用这两种集合时,需要注意它们内部实现的机制,以及泛型和Comparable接口的使用方法,确保业务逻辑得以正确实现。

标签:Comparable,set,HashSet,接口,Student,new,TreeSet
From: https://www.cnblogs.com/new-one/p/17346231.html

相关文章

  • rails的接口查询详解
    RetrievingObjectsfromtheDatabasefind"find"是一种常用的数据库查询方法,在Rails中被用于从数据库中查找单个记录。它可以接收一个主键作为参数,也可以接收一组条件参数。以下是"find"方法的使用方式:#使用主键查找单个记录Model.find(1)#使用条件参数查找单个记录Mod......
  • 容易忽视的细节:Log4j 配置导致的零点接口严重超时
    作者:vivo互联网服务器团队-JiangYe本文详细的记录了一次0点接口严重超时的问题排查经历。本文以作者自身视角极具代入感的描绘了从问题定位到具体的问题排查过程,并通过根因分析并最终解决问题。整个过程需要清晰的问题排查思路和丰富的问题处理经验,也离不开公司强大的调用链......
  • Vue Typescript 引入文件接口,就无法使用withDefaults
    就是代码写的不规范报错写法 import{Setting}from'@element-plus/icons-vue' import{defineProps,withDefaults}from'vue' import{PiProject}from'@/types/Project' interfaceProjectCardProps{ project:PiProject } constprops=de......
  • 常用代码-接口交互+构建页面
    点击#search,无参请求,构造表格代码:functiongetDataSet(){$("body").on("click","#search",function(){$.ajax({type:"get",url:"http://114.67.241.121:8080/product/list",......
  • Java接口
    Java接口Java接口的概述接口是一种公共的规范标准只要符合规范标准,就可以给大家通用生活举例接口的定义和基本格式接口是多个类的公共规范接口是一种引用数据类型,里面最重要的方法是抽象方法接口的格式publicinterface接口名称{接口内容}接口可以包含常量......
  • ZLMediaKit实现按需拉流时rtsp流地址不对addStreamProxy返回0,接口流id参数踩坑记录
    场景开源流媒体服务器ZLMediaKit在Windows上运行、配置、按需拉流拉取摄像头rtsp视频流)并使用http-flv网页播放:开源流媒体服务器ZLMediaKit在Windows上运行、配置、按需拉流拉取摄像头rts基于上面实现拉取视频流预览时,发现当调用api传参时如果更换了rtsp视频流地址,但是没有更改流......
  • Forest-声明式HTTP客户端框架-集成到SpringBoot实现调用第三方restful api并实现接口
    场景Forest声明式HTTP客户端API框架,让Java发送HTTP/HTTPS请求不再难。它比OkHttp和HttpClient更高层,是封装调用第三方restfulapiclient接口的好帮手,是retrofit和feign之外另一个选择。通过在接口上声明注解的方式配置HTTP请求接口。官网:Forest 代码地址:forest:声明式HTTP客户......
  • 冰橙GPT提供开放接口 。提供与OPENAI官方一致的体验效果(同步返回数据,同时支持流式及非
    冰橙GPTchatGPT开放接口使用说明 【接入了腾讯云内容安全检测】冰橙GPT稳定提供API接口服务定时有人进行问题排查处理1小时内问题响应接入了腾讯云的内容安全检测有任何疑问请加入QQ交流群:310872519           1.请求地址:https://gpt.bcwhkj.cn/a......
  • Java获取拼多多搜索词推荐 API接口(item_search_suggest-获得搜索词推荐)
    搜索词推荐的作用1.可以精准把控流量2.可以测试产品款式测试产品图片3.提升类目在平台的排名4.提升销量,加速报名参加平台的活动5.提升ROI,日常平销item_search_suggest-获得搜索词推荐公共参数名称类型必须描述keyString是调用key(必须以GET方式拼接在URL中)secretString是调用密钥(接......
  • 铺垫知识jwt工具类使用、登录接口实现细节分析和代码实现、测试接口
    铺垫知识jwt工具类使用JWT工具类:JWTUtilpublicstaticvoidmain(String[]args)throwsException{//加密Stringjwt=createJWT("2123");System.out.println(jwt);//解密Claimsclaims=parseJWT("eyJhbGciOiJIUzI1......