第7章-第4节-Java中的Set集合和自然排序compareble

news2024/9/21 2:38:53

1、HashSet:

1)、 Set集合的特点

  • 元素存储可以有序,可以无序(要看选择的具体子类 HashSet 无序 LinkedHashSet(有序),TreeSet(排序))

  • 没有索引,不能通过索引获取元素(即也不能使用普通for循环遍历)

  • 不可以存储重复的元素

    在某一些特定的场景,我们想要实现不能保存重复的元素的效果,此时使用Set集合就非常的合适

2)、 概述及特点

概述:HashSet集合是Set集合的子类,是一个具体的类。底层使用Hash表存储数据(hash本质就是一个数组)。HashSet存储数据使用的是HashMap的key部 分(HashMap我们明天会学习到,是一个双列的存储数据的结构)

存储数据的结构:数组 + 链表 + 红黑树

特点

  • 元素存储无序

  • 没有索引,不能通过索引获取元素(即也不能使用普通for循环遍历)

  • 不可以存储重复的元素

3)、 常用方法 

1>、增加:

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

public class AddDemo {
    public static void main(String[] args) {
        Set<Integer> set = new HashSet<>();
        // 添加元素
        set.add(1);
        set.add(2);
        set.add(3);
        set.add(17);
        System.out.println(set);

        Set<String> set2 = new HashSet<>();
        // 添加元素
        set2.add("zhangsan");
        set2.add("lisi");
        set2.add("wangwu");
        set2.add("zhaoliu");
        set2.add(null);// 允许添加null值,但是只能添加一次
        System.out.println(set2);
    }
}

2>、删除:

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

public class RemoveDemo {
    public static void main(String[] args) {
        Set<String> set = new HashSet<>();
        // 添加元素
        set.add("zhangsan");
        set.add("lisi");
        set.add("wangwu");
        set.add("zhaoliu");
        System.out.println(set);

        // 删除元素
        boolean flag = set.remove("zhangsan");
        System.out.println(flag);
        System.out.println(set);

        System.out.println("-----优雅的分隔符-----");

        // 删除部分元素
        Set<String> set2 = new HashSet<>();
        set2.add("lisi");
        set2.add("zhaoliu");
        set2.add("zhangsan");

        boolean result = set.removeAll(set2);
        System.out.println(result);
        System.out.println(set);
        
        // 清空集合
        set.removeAll(set);
        System.out.println(set);
        set.clear();
        System.out.println(set);
    }
}

3>、修改:

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

public class UpdateDemo {
    public static void main(String[] args) {
        Set<String> set = new HashSet<>();
        // 添加元素
        set.add("zhangsan");
        set.add("lisi");
        set.add("wangwu");
        set.add("zhaoliu");
        System.out.println(set);

        // 没有修改的方法
    }
}

4>、查询:

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

public class SelectDemo {
    public static void main(String[] args) {
        Set<String> set = new HashSet<>();
        // 添加元素
        set.add("zhangsan");
        set.add("lisi");
        set.add("wangwu");
        set.add("zhaoliu");
        System.out.println(set);

        // 获取集合的长度
        System.out.println(set.size());

        // 查询是否包含某一个指定的值
        boolean flag = set.contains("zhangsan");
        System.out.println(flag);

        // 集合是否为空
        System.out.println(set.isEmpty());

        // 增强for循环
        for(String str : set) {
            System.out.println(str);
        }

        System.out.println("----------------------");

        // 迭代器
        Iterator<String> iterator = set.iterator();
        while(iterator.hasNext()){
            String value = iterator.next();
            System.out.println(value);
        }
    }
}

4)、底层原理图:

备注:它的底层是用HashMap实现的, HashMap也是类似原理,后面章节会更具体的讲解HashMap。

2、TreeSet:

1)、学习了hashSet,无序不可重复。但是,有些时候,某些场景还是需要按照指定要求对数据进行排序。也就是说,要求我们的数据有序(此处 的有序指的不是存入顺序与取出顺序一致,而是按照指定的规则从大到小或者从小到大排序),比如,在录入学生考试成绩的时候 ,我就希望能够按照绩来进行排序。

很显然,这个功能使用HashSet没有办法实现,所以,我们需要学习TreeSet树结构,二叉树

2)、 概述及特点

概述:TreeSet实现了Set接口,存储的元素有序,可以按照一定的规则进行排序,具体排序方式取决于构造方法。

  • TreeSet():根据其元素的自然排序进行排序

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

    特点

  • 存储的元素有序

  • 没有带索引的方法,所以不能使用普通for循环遍历

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

    数据结构:采用的是红黑树的结构(本质上使用的是TreeMap的key部分)

    常用的方法与HashSet一致,这里不在进行演示,主要是讲解其排序的特点

3) 、保存基本数据类型及字符串

 1>、保存基本数据类型

import java.util.Set;
import java.util.TreeSet;

public class TreeSetDemo01 {
    public static void main(String[] args) {
        Set<Integer> set = new TreeSet<>();
        set.add(5);
        set.add(4);
        set.add(2);
        set.add(1);
        set.add(3);
        set.add(3);// 不能保存重复的元素
        System.out.println(set);// 保存的元素有序
    }
}

2>、保存字符串类型

import java.util.Set;
import java.util.TreeSet;

public class TreeSetDemo02 {
    public static void main(String[] args) {
        Set<String> set = new TreeSet<>();
        set.add("zhangsan");
        set.add("lisi");
        set.add("wangwu");
        set.add("zhaoliu");
        set.add("zhouqi");
        set.add("wangba");
        set.add("zhousan");// 不能存储重复的元素
        System.out.println(set);// 保存的元素有序
    }
}

3>、保存自定义类型

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

    public Student() {
    }

    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}
import java.util.Set;
import java.util.TreeSet;

public class TreeSetDemo03 {
    public static void main(String[] args) {
        Set<Student> set = new TreeSet<>();
        set.add(new Student("zhangsan", 21));
        set.add(new Student("lisi", 19));
        set.add(new Student("wangwu", 18));
        set.add(new Student("wangba", 23));
        System.out.println(set);// 保存的元素有序
    }
}

异常为:java.lang.ClassCastException: com.woniu.treeset.Student cannot be cast to java.lang.Comparable。

类型转换异常,说是Student 不能 转换为 Comparable。Comparable在我们的代码里面没有涉及到,为什么会出现这个问题呢?Integer,String也是引用类型,我们在使用的时候没有出现这异常呢。

所以,我们来看一下String的源码

 3、自然排序compareble:

comparable : 自然排序。是一个接口,只提供了一个方法:compareTo。就是排序的比较规则。如果使用TreeSet的无参构造方法保存自定义数据类型,那么该类应该实现comparable 接口,重写compareTo方法

public interface Comparable<T> {
    // 返回值为0,表示两个元素相等
    // 返回值为正整数,表示大于
    // 返回值为负整数,表示小于
    public int compareTo(T o);
}

案例演示

需求:存储学生对象并遍历,创建TreeSet集合使用无参构造方法。

要求:按照年龄从小到大排序。

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

    public Student() {
    }

    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
    
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public int compareTo(Student stu) {
        // 排序的规则
        // this表示需要添加进来的元素 --->         set.add(new Student("lisi", 19));  表示的是lisi
        // stu表示需要比较的对象,即已经存进集合里面的对象
        //System.out.println(stu.age + "---" + this.age);
        return this.age - stu.age;
    }
}
import java.util.Set;
import java.util.TreeSet;

public class TreeSetDemo03 {
    public static void main(String[] args) {
        Set<Student> set = new TreeSet<>();
        set.add(new Student("zhangsan", 21));
        set.add(new Student("lisi", 19));
        set.add(new Student("wangwu", 18));
        set.add(new Student("wangba", 23));

        set.add(new Student("zhouqi", 21));
        System.out.println(set);// 保存的元素有序
    }
}

本电子书目录:《Java基础的重点知识点全集》

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

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

相关文章

109.第一个qt项目

今天正式开始qt的学习。在安装完qt开发环境之后&#xff0c;下面我们来使用QtCreator创建项目。 1.创建项目 创建基于窗口的qt应用程序。选择编译套件, 编译套件用于项目文件的编译, 如果安装了多个编译套件, 在这里选择其中一个就可以了。选择版本控制工具。 2.项目文件&…

狂拿offer,这12道性能测试面试题你会多少?不要再被挖坑了

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、性能测试包含了…

使用Scrapy框架和代理IP进行大规模数据爬取

目录 一、前言 二、Scrapy框架简介 三、代理IP介绍 四、使用Scrapy框架进行数据爬取 1. 创建Scrapy项目 2. 创建爬虫 3. 编写爬虫代码 4. 运行爬虫 五、使用代理IP进行数据爬取 1. 安装依赖库 2. 配置代理IP和User-Agent 3. 修改爬虫代码 4. 运行爬虫 六、总结 一…

Verilog学习记录

目录 一、Verilog简介 &#xff08;一&#xff09;Verilog 的主要特性 &#xff08;二&#xff09;Verilog的主要应用 &#xff08;三&#xff09;Verilog设计方法 二、Verilog基础语法 &#xff08;一&#xff09;标识符和关键字 &#xff08;二&#xff09;Verilog数据…

多模态推荐系统综述:一、特征交互 Bridge

一、特征交互 挑战1.如何融合不同语义空间中的模态特征并获得每种模态的偏好。GNN注意力 挑战2.如何在数据稀疏的情况下获得推荐模型的全面表示。对比学习解缠学习 挑战3. 如何优化轻量级推荐模型和参数化模态编码器。 1. Bridge 侧重于考虑多模态信息来捕获用户和项目之间的…

Camtasia2024中文绿色版本下载安装详细步骤教程

Camtasia2024是一款功能强大的屏幕录制和视频编辑软件。它可以帮助用户轻松地记录电脑屏幕上的任何操作&#xff0c;并可以将录制的视频进行编辑和制作成高质量的视频教程、演示文稿、培训课程等。 Camtasia具有直观的界面和易于使用的工具&#xff0c;包括添加文本、音频、动…

深度学习|4.7 参数和超参数

4.7 参数和超参数 超参数是指需要用户提前设置好的参数&#xff0c;这些超参数最终会影响到参数的数值&#xff08;相当于参数是动态调整得到的&#xff09; 学习率的选取 最优学习率应该能使得代价函数趋于一个较低的常数。

【金猿CIO展】是石科技CIO侯建业:算力产业赋能,促进数字经济建设

‍ 侯建业 本文由是石科技CIO侯建业撰写并投递参与“数据猿年度金猿策划活动——2023大数据产业年度优秀CIO榜单及奖项”评选。 大数据产业创新服务媒体 ——聚焦数据 改变商业 是石科技&#xff08;江苏&#xff09;有限公司成立于2021年&#xff0c;由国家超级计算无锡中心与…

信息系统安全——基于 KALI 和 Metasploit 的渗透测试

实验 2 基于 KALI 和 Metasploit 的渗透测试 2.1 实验名称 《基于 KALI 和 Metasploit 的渗透测试》 2.2 实验目的 1 、熟悉渗透测试方法 2 、熟悉渗透测试工具 Kali 及 Metasploit 的使用 2.3 实验步骤及内容 1 、安装 Kali 系统 2 、选择 Kali 中 1-2 种攻击工具&#xff0c…

x-cmd pkg | usql - SQL 数据库的通用交互界面

目录 简介首次用户功能特点竞品和相关作品进一步阅读 简介 “usql” 是一个基于命令行的数据库客户端工具&#xff0c;它允许用户连接和管理多种类型的数据库。usql可以在多个操作系统上运行&#xff0c;包括 Linux、macOS 和 Windows。它还具有插件系统&#xff0c;可以根据需…

一文读懂「Self Attention」自注意力机制

前言&#xff1a;Self-Attention是 Transformer 的重点&#xff0c;因此需要详细了解一下 Self-Attention 的内部逻辑。 一、什么是自注意力机制&#xff1f; 就上图为例&#xff0c;老实告诉我当你第一眼看到上图时&#xff0c;你的视线停留在哪个位置&#xff1f;对于我这种…

鸿蒙开发之如何查看界面层级

首先&#xff0c;需要是在真机或模拟器已经是run的状态。 然后点击deveco studio 的 tools工具栏的ArkUl Inspector 然后界面下面显示出层级显示卡&#xff0c;但还看不到 然后选择一下进程please select a process 就能显示了

【Android Studio】创建第一个APP工程及生成APK安装包

&#x1f31f;博主领域&#xff1a;嵌入式领域&人工智能&软件开发 前言&#xff1a;本文详细介绍创建Android Studio第一个APP工程及打包生成APK安装包。 如下两个博客我记录了第一次创建项目时出现的问题&#xff0c;若你也遇见了同样的问题&#xff0c;可参考&#…

vue简体繁体互转无需做字库

第一种方法 vue-i18n 需要自己写字库库很麻烦,而且不支持后端传值 第二种 opencc 这个库前端去使用的时候 数据较多的情况非常慢.影响使用 第三种 language-hk-loader npm i language-hk-loader 从其他博客中看到的一种,很方便不需要写字库,但是在打包的时候去整体的去翻译…

基于深度学习的停车位关键点检测系统(代码+原理)

摘要&#xff1a; DMPR-PS是一种基于深度学习的停车位检测系统&#xff0c;旨在实时监测和识别停车场中的停车位。该系统利用图像处理和分析技术&#xff0c;通过摄像头获取停车场的实时图像&#xff0c;并自动检测停车位的位置和状态。本文详细介绍了DMPR-PS系统的算法原理、…

【Scala】——变量数据类型运算符

1. 概述 1.1 Scala 和 Java 关系 1.2 scala特点 Scala是一门以Java虚拟机&#xff08;JVM&#xff09;为运行环境并将面向对象和函数式编程的最佳特性结合在一起的静态类型编程语言&#xff08;静态语言需要提前编译的如&#xff1a;Java、c、c等&#xff0c;动态语言如&#…

vue3 响应式api中特殊的api

系列文章目录 TypeScript 从入门到进阶专栏 文章目录 系列文章目录一、shallowRef()二、triggerRef()三、customRef()四、shallowReactive()五、shallowReadonly()六、toRaw()七、markRaw()八、effectScope()九、getCurrentScope() 一、shallowRef() shallowRef()是一个新的响…

我是内网灵活的狗之渗透之红日靶场 stack之用户域渗透

接上回 我们现在准备对域内的用户靶机进行一下扫描 因为对所有的端口进行扫描的话 会导致扫描时间过长 我们这里只对部分重要端口进行扫描 看见445端接口开着&#xff0c;所以我们尝试连接445 的漏洞 用永恒之蓝漏洞连接后&#xff0c;尝试用这个漏洞&#xff0c;添加新的用…

代码随想录day22 二叉树开始进入无固定方法阶段

235. 二叉搜索树的最近公共祖先 题目 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个结点 p、q&#xff0c;最近公共祖先表示为一个结点 x&#xff0c;满足 x 是 p、q 的祖先且 x 的深度尽可…

小程序实现绘制图片 保存到手机

HTML <template><view><canvas canvas-id"myCanvas" :style"{height:380px,width:wWidthpx,background:#FFFFFF}"></canvas><view class"textCenter"><button click"saveCanvas">保存图片</b…