Java中的Set系列集合超详解

 Set

 List是有序集合的根接口,Set是无序集合的根接口,无序也就意味着元素不重复。更严格地说,Set集合不包含一对元素e1和e2 ,使得e1.equals(e2) ,并且最多一个空元素。
  使用Set存储的特点与List相反:元素无序、不可重复。常用的实现方式:HashSet、LinkedHashSet和TreeSet。

Set系列集合概述和特点

  • 底层数据结构是哈希表

  • 存取无序

  • 不可以存储重复元素

  • 没有索引,不能使用普通for循环遍历

set集合的基本应用

 public static void main(String[] args) {Set<String> s=new HashSet<String>();boolean flag1= s.add("aaa");boolean flag2 = s.add("aaa");System.out.println(flag1);System.out.println(flag2);System.out.println(s);//如果当前元素是第一次添加,那么可以添加成功,返回true//如果当前元素是第二次添加,那么添加失败,返回false}

        

存储字符串并遍历

方式一迭代器方式

 public static void main(String[] args) {Set<String> s=new HashSet<String>();s.add("张三");s.add("李四");//迭代器Iterator<String> it = s.iterator();while(it.hasNext()){String str = it.next();System.out.println(str);}}

方式2-增强for

//增强forfor (String str : s) {System.out.println(str);}

方式3lambda表达式

 // Lambda表达式s.forEach((String str)-> System.out.println(str));

总结

HashSet集合概述和特点

  • 底层数据结构是哈希表

  • 存取无序

  • 不可以存储重复元素

  • 没有索引,不能使用普通for循环遍历

哈希值

  • 哈希值简介

    是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值

  • 如何获取哈希值

    Object类中的public int hashCode():返回对象的哈希码值

  • 哈希值的特点

    • 同一个对象多次调用hashCode()方法返回的哈希值是相同的

    • 默认情况下,不同对象的哈希值是不同的。而重写hashCode()方法,可以实现让不同对象的哈希值相同

package set;
/*哈希值:对象的整数表现形式1. 如果没有重写hashCode方法,不同对象计算出的哈希值是不同的2. 如果已经重写hashcode方法,不同的对象只要属性值相同,计算出的哈希值就是一样的3. 但是在小部分情况下,不同的属性值或者不同的地址值计算出来的哈希值也有可能一样。(哈希碰撞)*/
public class demo3 {public static void main(String[] args) {//   1. 如果没有重写hashCode方法,不同对象计算出的哈希值是不同的Student s1 = new Student("zhangsan",18);Student s2 = new Student("zhangsan",18);/*  System.out.println(s1.hashCode());//189568618System.out.println(s2.hashCode());//793589513*///不一样,所以我们要重写hashCode()//  2. 如果已经重写hashcode方法,不同的对象只要属性值相同,计算出的哈希值就是一样System.out.println("------------------");System.out.println(s1.hashCode());//1461067297System.out.println(s2.hashCode());//1461067297// 3. 但是在小部分情况下,不同的属性值或者不同的地址值计算出来的哈希值也有可能一样。(哈希碰撞)//哈希碰撞System.out.println("abc".hashCode());//96354System.out.println("acD".hashCode());//96354}
}

练习

package lx;import java.util.HashSet;public class demo1 {public static void main(String[] args) {Student s1 = new Student("张三", 8);Student s2 = new Student("张三", 8);Student s3 = new Student("李四", 18);Student s4 = new Student("王五", 17);HashSet<Student> set = new HashSet<Student>();set.add(s1);set.add(s2);set.add(s3);set.add(s4);//重写hashCode方法就可以去重复的对象//因为重写hashCode方法,比的是属性值,属性值一样,哈希值一样,所以添加不成功//不重写比的是地址值,创建出来的对象地址值永远不一样,所以哈希值不一样,所以添加成功//如果已经重写hashcode方法,不同的对象只要属性值相同,计算出的哈希值就是一样//重写equals方法也一样 比的也是地址值,不是属性值for (Student student : set) {System.out.println(student);}}
}

注意像String Integer类型的,Java已经在底层重写好了HashSet和equals方法

LinkedHashSet

package LinkedHashSet;import lx.Student;import java.util.HashSet;
import java.util.LinkedHashSet;public class demo1 {public static void main(String[] args) {Student s1 = new Student("张三", 8);Student s2 = new Student("张三", 8);Student s3 = new Student("李四", 18);Student s4 = new Student("王五", 17);LinkedHashSet<Student> set = new LinkedHashSet<Student>();set.add(s3);set.add(s1);set.add(s3);set.add(s4);//LinkedHashSet的存和去顺序一样for (Student student : set) {System.out.println(student);}}
}

 

TreeSet

package TreeSet;import java.util.TreeSet;public class demo1 {public static void main(String[] args) {//利用TreeSet对整数进行排序//默认升序TreeSet<Integer> ts = new TreeSet<>();//添加元素ts.add(4);ts.add(2);ts.add(5);ts.add(8);ts.add(1);//使用增强forfor (Integer t : ts) {System.out.print(t + " ");}}
}

package TreeSet;import java.util.TreeSet;public class demo2 {public static void main(String[] args) {//利用TreeSet对String类型进行排序TreeSet<String> ts = new TreeSet<>();ts.add("va");ts.add("aaa");ts.add("ha");ts.add("aba");ts.add("acd");for (String t : ts) {System.out.print(t + " ");}}
}

练习

 @Overridepublic int compareTo(Student o) {//只看年龄按照升序排序int tmp=this.getAge() - o.getAge();tmp= tmp==0?this.getName().compareTo(o.getName()):tmp;return tmp;}
package TreeSet;import javax.print.DocFlavor;
import java.util.TreeSet;
import java.util.function.Consumer;public class demo3 {public static void main(String[] args) {//利用TreeSet对学生类型进行排序TreeSet<Student> ts = new TreeSet<>();//要求: 按照学生的年龄进行排序//同年按照姓名字母排序//同姓名,同年龄认为同一个人Student s1 = new Student("zhangsan", 18);Student s2 = new Student("lisi", 19);Student s3 = new Student("wangwu", 19);ts.add(s2);ts.add(s3);ts.add(s1);System.out.println(ts);//方式一:默认的排序方式,Student实现一个接口(comparable接口)重写里面的抽象方法//再指定比较规则//hashCode和equals方法跟哈希表有关//TreeSet底层红黑树有关//所以不需要重写hashCode和equals方法}
}

package TreeSet;import java.util.Comparator;
import java.util.TreeSet;public class demo4 {public static void main(String[] args) {//方法二:比较器排序//1.创建集合//2.o1表示当前要添加的元素//3.o2表示已经在红黑树存在的元素//返回值规则跟之前一样TreeSet<String> ts = new TreeSet<>(new Comparator<String>() {@Override/*需求:请自行选择比较器排序和自然排序两种方式;要求:存入四个字符串, “c”, “ab”, “df”, “qwer”按照长度排序,如果一样长则按照首字母排序采取第二种排序方式:比较器排序*/public int compare(String o1, String o2) {//按照长度来int tmp = o1.length() - o2.length();//如果一样长则按照首字母排序tmp = tmp == 0 ? o1.compareTo(o2) : tmp;return tmp;}});//2.添加元素ts.add("c");ts.add("ab");ts.add("df");ts.add("qwer");System.out.println(ts);}
}

package lx2;import java.util.TreeSet;/*  需求:创建5个学生对象属性:(姓名,年龄,语文成绩,数学成绩,英语成绩),按照总分从高到低输出到控制台如果总分一样,按照语文成绩排如果语文一样,按照数学成绩排如果数学成绩一样,按照英语成绩排如果英文成绩一样,按照年龄排如果年龄一样,按照姓名的字母顺序排如果都一样,认为是同一个学生,不存。第一种:默认排序/自然排序第二种:比较器排序默认情况下,用第一种排序方式,如果第一种不能满足当前的需求,采取第二种方式。课堂练习:要求:在遍历集合的时候,我想看到总分。*/
public class demo1 {public static void main(String[] args) {//1.创建学生对象Student s1 = new Student("zhangsan", 23, 90, 99, 50);Student s2 = new Student("lisi", 24, 90, 98, 50);Student s3 = new Student("wangwu", 25, 95, 100, 30);Student s4 = new Student("zhaoliu", 26, 60, 99, 70);Student s5 = new Student("qianqi", 26, 70, 80, 70);TreeSet<Student> st=new TreeSet<>();st.add(s1);st.add(s2);st.add(s3);st.add(s4);st.add(s5);for (Student student : st) {System.out.println(student);}}
}

package lx2;//第一种:默认排序/自然排序
public class Student implements Comparable<Student> {private String name;private int age;//语文成绩private int chinese;//数学成绩private int math;//英语成绩private int english;public Student() {}public Student(String name, int age, int chinese, int math, int english) {this.name = name;this.age = age;this.chinese = chinese;this.math = math;this.english = english;}/*** 获取** @return name*/public String getName() {return name;}/*** 设置** @param name*/public void setName(String name) {this.name = name;}/*** 获取** @return age*/public int getAge() {return age;}/*** 设置** @param age*/public void setAge(int age) {this.age = age;}/*** 获取** @return chinese*/public int getChinese() {return chinese;}/*** 设置** @param chinese*/public void setChinese(int chinese) {this.chinese = chinese;}/*** 获取** @return math*/public int getMath() {return math;}/*** 设置** @param math*/public void setMath(int math) {this.math = math;}/*** 获取** @return english*/public int getEnglish() {return english;}/*** 设置** @param english*/public void setEnglish(int english) {this.english = english;}public String toString() {return "Student{name = " + name + ", age = " + age + ", chinese = " + chinese + ", math = " + math + ", english = " + english + "}";}@Overridepublic int compareTo(Student o) {/* 按照总分从高到低输出到控制台如果总分一样,按照语文成绩排如果语文一样,按照数学成绩排如果数学成绩一样,按照英语成绩排如果英文成绩一样,按照年龄排如果年龄一样,按照姓名的字母顺序排如果都一样,认为是同一个学生,不存。*/int sum1 = this.getChinese() + this.getMath() + this.getEnglish();int sum2=o.getChinese() + o.getMath() + o.getEnglish();int tmp = sum2-sum1;// 如果总分一样,按照语文成绩排tmp = tmp == 0 ? this.getChinese() - o.getChinese() : tmp;// 如果语文一样,按照数学成绩排tmp = tmp == 0 ? this.getMath() - o.getMath() : tmp;//如果数学成绩一样,按照英语成绩排tmp = tmp == 0 ? this.getEnglish() - o.getEnglish() : tmp;//如果英文成绩一样,按照年龄排tmp = tmp == 0 ? this.getAge() - o.getAge() : tmp;// 如果年龄一样,按照姓名的字母顺序排tmp = tmp == 0 ? this.getName().compareTo(o.getName()) : tmp;return tmp;}
}

TreeSet二种排序方式



总结

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/870874.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

腾讯云如何设置二级域名?

什么是二级域名&#xff1f; 例如我已申请的域名为&#xff1a; test.com //顶级域名 现在我开发的应用要部署到二级域名&#xff1a; blog.test.com 1、打开腾讯云控制台的我的域名&#xff0c;然后点击解析 2、在我的解析页面点击添加记录&#xff0c;然后需注意红色方框处…

生物素标记的柚皮苷探针;Biotin-Naringin

生物素标记的柚皮苷探针&#xff08;Biotin-Naringin&#xff09;是一种结合了生物素&#xff08;Biotin&#xff09;和柚皮苷&#xff08;Naringin&#xff09;特性的化合物&#xff0c;它在有机合成及药物化学技术领域具有重要意义。以下是对该探针的详细解析&#xff1a; 一…

秋招Java后端开发冲刺——Mybatis

一、基本知识 1. 介绍 MyBatis 是 Apache 的一个开源项目&#xff0c;它封装了 JDBC&#xff0c;使开发者只需要关注 SQL 语句本身&#xff0c;而不需要再进行繁琐的 JDBC 编码。MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java POJO&#xff08;Plain …

设计模式Base

设计模式是在软件开发过程中总结出来的一些经验&#xff0c;它们大多数都遵循一些基本原则&#xff1a; 单一职责原则&#xff08;SRP&#xff09;&#xff1a;一个类应该只有一个引起它变化的原因。也就是说&#xff0c;一个类应该只有一个职责。开放封闭原则&#xff08;OCP…

Everything搜索无法搜索到桌面的文件(无法检索C盘 或 特定路径的文件)

现象描述 在Everything搜索框中输入桌面已存在的文件或随便已知位置的文件&#xff0c;无法找到。 搜索时检索结果中明显缺少部分磁盘位置的&#xff0c;例如无法检索C盘&#xff0c;任意关键字搜索时结果中没有位于C盘的&#xff0c;无论怎样都搜不到C盘文件。 解决方法 在…

CentOS搭建FTP服务器教程

CentOS搭建FTP服务器教程 在互联网时代&#xff0c;文件传输是日常工作中不可或缺的一部分。FTP&#xff08;文件传输协议&#xff09;作为一种标准的网络协议&#xff0c;被广泛用于在互联网上传输文件。本文将详细介绍如何在CentOS系统上搭建FTP服务器&#xff0c;以便您能轻…

L1 Simple_ReAct_Agent

参考自https://www.deeplearning.ai/short-courses/ai-agents-in-langgraph&#xff0c;以下为代码的实现。 Basic ReAct Agent(manual action) import openai import re import httpx import os from dotenv import load_dotenv, find_dotenvOPENAI_API_KEY os.getenv(OPEN…

pip install .自己构建工程文件报错error: subprocess-exited-with-error解决办法

有时我们直接使用pip install xxx安装某个三方文件时候会发现安装不了,会报各种问题。 这时候我们只能通过下载源码自己手动编译。 等我们下好源码开始编译的时候又会出现很多问题。 下面就举一个栗子作为解决问题的思路: 比如我我想要安装diff-gaussian-rasterization,直…

python 66 个冷知识 0712

66个有趣的Python冷知识 字典合并 从Python 3.9开始&#xff0c;可以使用 | 操作符合并字典。 多继承 Python支持多继承&#xff0c;类可以继承多个父类。 ABC模块 abc 模块提供了定义抽象基类的工具。 泛型 typing 模块提供了泛型支持。 类型别名 使用 typing 模块可以创建…

DP讨论——设计模式怎么来的?

眼中没有设计模式&#xff0c;代码里就找不到设计模式 几年前还在搞c开发&#xff0c;觉得设计模式离我太遥远&#xff0c;而且觉得设计模式太复杂太高大上&#xff0c;比较恐惧。 后来接触了oopc&#xff08;接触了rtthread整个都是oopc实现的rtos&#xff09;&#xff0c;再…

LTE系统OFDM符号持续时间计算

LTE系统OFDM符号持续时间计算 给定等式&#xff1a;7个OFDM符号的持续时间 0.5ms(1个slot) - 160Ts - 6144*Ts 其中&#xff1a; 1个slot 0.5msTs是LTE系统的基本时间单位 步骤分解 理解时间资源结构&#xff1a; 1个无线帧 10ms1个子帧 1ms 2个slot1个slot 0.5ms1个…

Spring Boot Vue 毕设系统讲解 9 【Spark】

SuppressWarnings("serial") Configuration ConfigurationProperties(prefix"spark") public class SparkConfig implements Serializable {//spark的安装地址private String sparkHome ".";//应用的名称private String appName "mySpar…

图像识别和目标检测在超市电子秤上的应用

目录 前言深度学习的目标检测图像识别技术视觉秤的优势其他应用场景中的技术应用未来展望 前言 随着科技的不断发展&#xff0c;电子秤在生鲜超市中的应用也在不断升级。传统的电子秤需要打秤人员手动输入秤码&#xff0c;这不仅耗时费力&#xff0c;还需要大量的培训以记住各…

Rust编程-泛型、Trait和生命周期

泛型&#xff1a; 泛型是类型编程中的一种工具。本质上是类型的变量&#xff0c;目的是提高代码的复用。泛型是 具体类型或其他属性的抽象替代。 为了复用&#xff0c;我们会使用函数将功能封装&#xff0c;同样&#xff0c;泛型也是为了复用&#xff0c;只不过是为了类型的复用…

工业大数据是什么?应用工业大数据时面临哪些挑战?

在当今快速发展的工业领域&#xff0c;大数据已成为推动企业转型升级的核心动力。工业大数据&#xff0c;以其独特的价值和潜力&#xff0c;正逐渐改变着传统的生产、管理和决策模式。然而&#xff0c;伴随着大数据的快速发展&#xff0c;一系列挑战也随之浮现。本文将深入探讨…

算法日常练习

对于这个题&#xff0c;如何处理同一个方向的问题&#xff0c;且对于同一组的如果间隔太大如何实现离散化 #include<bits/stdc.h> using namespace std;#define int long long typedef long long ll; map<pair<int,int>,vector<pair<ll,ll>>> mp…

关于机械键盘的购买,该怎么选择?

一.关于轴体的选择。 1.青轴&#xff1a;青轴是机械键盘最有段落感的轴&#xff0c;声音比较大&#xff0c;以吵死人别人著称。有人将其比喻为Cherry的春天&#xff0c;爽快清脆的段落感如春天般舒畅。适合在宿舍、咖啡厅&#xff0c;图书馆使用。&#xff08;我装的 &#xf…

C++ STL std::lexicographical_compare用法和实现

一&#xff1a;功能 按字典顺序比较两个序列&#xff0c;判断第一个序列是否小于(或大于)第二个序列 二&#xff1a;用法 #include <compare> #include <vector> #include <string> #include <algorithm> #include <iostream> #include <fo…

linux源码安装mysql8.0的小白教程

1.下载8.x版本的mysql MySQL :: Download MySQL Community Server (Archived Versions) 2.安装linux 我安装的是Rocky Linux8.6 3.设置ip地址,方便远程连接 使用nmcli或者nmtui设置或修改ip地址 4.使用远程连接工具MobaXterm操作: (1)将mysql8版本的压缩包上传到mybaxterm…

数据建设实践之大数据平台(三)安装hadoop

安装hadoop 上传安装文件到/opt/software目录并解压 [bigdata@node101 software]$ tar -zxvf hadoop-3.3.5.tar.gz -C /opt/services/ 配置环境变量 [bigdata@node101 ~]$ sudo vim /etc/profile.d/bigdata_env.sh export JAVA_HOME=/opt/services/jdk1.8.0_161 export ZK…