Java中的集合(二)

news2024/11/19 12:41:11

一、回顾上期

       上一篇讲到在Java中,集合和容器是非常重要的概念,用于存储和操作数据。在集合中,有单列集合和双列集合两种类型。我们在上一篇将单列集合中的list类讲完了,这一篇将会将集合中剩余部分介绍完,话不多说,那就开始吧!

二、单列集合中的set集合

        话说单列集合中,分为两类,一种是list类,一种是set类;两类都是实现了Collection接口,有着一些共同的方法,那既然有了list我们为何还要又单独定义一个set类呢

        原来,list类的出现更加类似与数组这样线性的存储结构,而set的出现是为了方便操作,两者的实现目的不同,所以使用场景和底层逻辑也有所不同,正因如此,list允许集合中出现重复元素而set不允许。

        set集合中共有两个子类,hashSet(无序)、TreeSet(有序)

(1)HashSet

hashSet是set集合的子类之一,具有如下特点

  1. 不允许重复元素:HashSet中不允许存储重复元素,每个元素在HashSet中只会出现一次。当尝试向HashSet中添加重复元素时,新元素不会被添加进集合。

  2. 无序性:HashSet中的元素没有固定的顺序,即不保证元素的顺序与插入顺序相同。这是因为HashSet内部使用哈希表来存储元素,元素的存储位置是根据元素的哈希码决定的。

  3. 高效的查找操作:由于HashSet基于哈希表实现,查找元素的效率很高。当需要判断某个元素是否存在于HashSet中时,HashSet会通过计算元素的哈希码来快速找到对应的存储位置,从而实现快速的查找操作。

  4. 添加、删除元素效率高:HashSet对于添加和删除元素的操作效率也很高,因为它们都可以通过哈希码快速定位到元素的存储位置。

hashSet主要的方法如下(成员方法,需要定义hashSet对象)

set.clear();//清空
set.contains();//判断是否包含某一元素
set.remove();//删除
set.iterator();//获取迭代器对象

 hashSet的主要遍历方式

1、使用迭代器(Iterator)进行遍历:

Set<Object> hashSet = new HashSet<>();
// 添加元素到HashSet
hashSet.add("Apple");
hashSet.add("Banana");
hashSet.add("Orange");

Iterator<Object> iterator = hashSet.iterator();
while (iterator.hasNext()) {
    Object element = iterator.next();
    // 处理每个元素
    System.out.println(element);
}

2、使用增强型for循环进行遍历:

Set<Object> hashSet = new HashSet<>();
// 添加元素到HashSet
hashSet.add("Apple");
hashSet.add("Banana");
hashSet.add("Orange");

for (Object element : hashSet) {
    // 处理每个元素
    System.out.println(element);
}

不知道大家看到这里会不会好奇,当set集合添加元素时如何判断元素重复的?

        如果每次都使用equals效率很低,肯定不是hashSet底层所使用的。其实在底层使用的是hashCode();

Object的hashCode的方法是判断地址,而Set集合调用的是重写的hashCode方法,根据内容计算哈希值;遍历时会先使用哈希值比较是否相等,再使用equals,这既保证效率又保证安全。我们使用的基本数据类型包装类中都已经将hashCode()方法重写过,可以放心使用。但是当我们自定义一个数据类型时,就需要重写hashCode()方法,以确保HashSet集合可以很好的比较和排序

例如我们写一个学生类型,包括成员变量姓名、年龄;可以这样写

@Override
public int hashCode() {
    int result = name != null ? name.hashCode() : 0;
    result = 31 * result + age;
    return result;
}
(2)TreeSet

TreeSet是Set接口的另一个常见实现类,它基于红黑树(Red-Black Tree)实现,具有以下特点:

  1. 自动排序:TreeSet中的元素会按照它们的自然顺序(natural ordering)或者通过Comparator接口指定的顺序进行排序。当元素被添加到TreeSet中时,它们会被自动排序,这使得TreeSet是一个有序的集合。

  2. 不允许重复元素:与HashSet类似,TreeSet中不允许存储重复元素,每个元素在TreeSet中只会出现一次。

  3. 高效的查找操作:由于TreeSet内部基于红黑树实现,查找、插入、删除元素的操作效率都很高。红黑树是一种自平衡的二叉搜索树,保证了元素的快速查找和操作。

  4. 提供有序性:TreeSet中的元素是有序的,可以根据元素的自然顺序或者指定的排序规则进行遍历。这使得TreeSet适合需要有序集合的场景。

话不多说,直接上方法

TreeSet<Integer> set =new TreeSet<>();
        set.add(3);
        set.add(4);
        set.add(1);
        set.add(2);
        set.add(3);
        System.out.println(set);//[1, 2, 3, 4]
        set.clear();//清空
        set.size();//长度
        set.contains("");//是否包含某一元素
        set.first();//删除并返回第一个元素
        set.isEmpty();//判断是否为空
        set.remove(1);//删除指定元素
        set.pollLast();//删除并返回最后一个元素

 需要注意的是:TreeSet中的元素必须实现Comparable接口并且重写compareTo()方法,用于确定排序的规则,话不多说,上案例

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

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


  

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


    @Override
    public int compareTo(Student o) {
        return this.age-o.age;
    }
}

三、双列集合

双列集合是一种数据结构,它包含一组成对的元素,每个元素都包含两部分:一个键和一个值。

在Java中,双列集合通常使用Map接口及其实现类来表示。Map接口表示一种键值对的映射关系,常用的实现类有HashMapTreeMap、HashTable等。

1、hashMap--基于哈希表实现,可以提供快速的插入、查找和删除操作。

常用方法:

public static void main(String[] args) {
        HashMap<String,String> map =new HashMap<>();
        map.put("c","cc");//添加
        map.put("x","xx");
        map.put("z","zz");
        map.put("a","aa");
        map.put("c","CC");
        map.put("h","hh");
        System.out.println(map);

        map.get("c");//输入key获取value
        map.clear();//清空
        map.remove("h");//输入key删除这个键值对并返回value
        map.containsKey("k");//判断是否包含该键,返回布尔值
        map.containsValue("aa");//判断是否包含这个值,返回布尔值
        map.isEmpty();//判断是否为空返回布尔值
        map.size();//返回键值对数量
        map.values();//将所有的值存入单列集合 Collection类型对象接收
        map.keySet();//将所有的key存入set集合 set类型对象接收



    }

遍历

public static void main(String[] args) {
        HashMap<String,String> map =new HashMap<>();
        map.put("c","cc");//添加
        map.put("x","xx");
        map.put("z","zz");
        map.put("a","aa");
        map.put("c","CC");
        map.put("h","hh");

        //方式1 同过map.set将所有key存入集合,通过map.get获取value
        Set<String> keySet =map.keySet();
        for(String key:keySet){
            System.out.println(key+":"+map.get(key));
        }


        System.out.println();


        //方式2:map.entrySet();返回一个Entry类的集合,Entry里包含键值对
        //Entry包含相关方法
        Set<Map.Entry<String,String>>entries=map.entrySet();
        for(Map.Entry<String,String> entry:entries){
            System.out.println(entry.getKey()+entry.getValue());
        }
    }

put方法的底层逻辑

2、TreeMap--TreeMap是Java中另一个常用的双列集合,它基于红黑树实现,可以提供按照键的顺序进行遍历的特性。

package com.wbc.javaclllection.Map双列集合.TreeMap;

import java.util.TreeMap;

public class TreeMapDemo {
    /*
    map: 键值对 键不能重复 值可以重复
    TreeMap:键可以排序 底层使用树结构 键的类型必须实现Comparable接口
     */
    public static void main(String[] args) {
        TreeMap<Integer,String> treeMap =new TreeMap<>();
        treeMap.put(1,"a");
        treeMap.put(2,"c");
        treeMap.put(5,"d");
        treeMap.put(4,"e");
        treeMap.put(3,"a");
        System.out.println(treeMap);

        //方法与HashMap一致
    }
}

3、HashTable--类似于HashMap,也是基于哈希表实现的。

HashTable底层与HashMap相同,但是HashTable是线程安全的
方法多了一个synchronized关键字
HashMap可以有一个键为null、值也可以为null,HashTable不能存储null,键值都不行

四、本章结构--思维导图

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

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

相关文章

备战蓝桥杯---刷二分与前缀和题

刷点题~ 1.二分多路归并算法 对于每一个技能&#xff0c;我们把它看成一个等差数列&#xff0c;我们把所有可能都放到一个集合里&#xff0c;排个序&#xff0c;取前m个大即可&#xff0c;现在考虑优化&#xff0c;假如m不是很大&#xff0c;我们直接用优先队列即可&#xff0…

单细胞RNA测序(scRNA-seq)SRA数据下载及fastq-dumq数据拆分

单细胞RNA测序&#xff08;scRNA-seq&#xff09;入门可查看以下文章&#xff1a; 单细胞RNA测序&#xff08;scRNA-seq&#xff09;工作流程入门 单细胞RNA测序&#xff08;scRNA-seq&#xff09;细胞分离与扩增 1. NCBI查询scRNA-seq SRA数据 NCBI地址&#xff1a; https…

继承.Java

目录 1&#xff0c;概述 1.1继承的含义 1.2什么时候用继承 1.3继承的好处 1.4继承的特点 2&#xff0c;继承的格式 3&#xff0c;可以继承哪些内容 4&#xff0c;成员方法和成员变量的访问特点 5&#xff0c;构造方法的访问特点 6&#xff0c;this&#xff0c;super…

windows版本-idea中下载的java版本在哪

1、点击idea的file-projectStructure 进入&#xff1a; 通过电脑目录进入该目录 找到bin目录&#xff0c;copy该目录地址 copy下来之后设置到系统环境变量中

C#项目引用解决方案中其他项目dll时,出现黄色感叹号的解决方案

问题引入 今天拿着老师傅的老项目&#xff0c;需要做通讯调试&#xff0c;说测试一下&#xff0c;便添加了一个项目A来编写结构体&#xff0c;然后在窗体程序项目B中引用A&#xff0c;发现B一引用A&#xff0c;在B项目的引用下面A就多了个黄色感叹号&#xff0c;一编译B项目&am…

瑞_Redis_商户查询缓存

文章目录 项目介绍1 短信登录2 商户查询缓存2.1 什么是缓存2.1.1 缓存的应用场景2.1.2 为什么要使用缓存2.1.3 Web应用中缓存的作用2.1.4 Web应用中缓存的成本 2.2 添加Redis缓存2.2.1 背景2.2.2 缓存模型和思路2.2.3 代码实现2.2.4 测试附&#xff1a;IDEA控制台输出自动换行设…

色域(BT2020/BT709/sRGB/DCI-P3/Rec.709/NTSC)

什么是色域 色域是对一种颜色进行编码的方法&#xff0c;也指一个技术系统能够产生的颜色的总和。在计算机图形处理中&#xff0c;色域是颜色的某个完全的子集。一般来说&#xff0c;高端投影仪和电视都会强调色域范围和对比度&#xff0c;而不是唯亮度标准论。 自然界可见光…

面试算法-139-盛最多水的容器

题目 给定一个长度为 n 的整数数组 height 。有 n 条垂线&#xff0c;第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线&#xff0c;使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。 说明&#xff1a;你不能倾斜容器。…

Sybase ASE中的char(N)的坑以及与PostgreSQL的对比

1背景 昨天,一朋友向我咨询Sybase ASE中定长字符串类型的行为,说他们的客户反映,同样的char类型的数据,通过jdbc来查,Sybase库不会带空格,而PostgreSQL会带。是不是这样的?他是PostgreSQL的专业大拿,但因为他手头没有现成的Sybase ASE环境,刚好我手上有,便于一试。 …

(学习日记)2024.04.01:UCOSIII第二十九节:消息队列实验(待续)

写在前面&#xff1a; 由于时间的不足与学习的碎片化&#xff0c;写博客变得有些奢侈。 但是对于记录学习&#xff08;忘了以后能快速复习&#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位&#xff0c;以时间为顺序&#xff0c;仅仅将博客当做一个知识学习的目录&a…

LearnOpenGL_part1

创建窗口 - LearnOpenGL CN (learnopengl-cn.github.io) 最原始的黑框框&#xff1a; #include <glad/glad.h> #include <GLFW/glfw3.h> #include <iostream> int main() {glfwInit();//初始化GLFWglfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);//配置G…

亚马逊AWS永久免费数据库

Amazon DynamoDB 是一项无服务器的 NoSQL 数据库服务&#xff0c;您可以通过它来开发任何规模的现代应用程序。作为无服务器数据库&#xff0c;您只需按使用量为其付费&#xff0c;DynamoDB 可以扩展到零&#xff0c;没有冷启动&#xff0c;没有版本升级&#xff0c;没有维护窗…

如何同时安全高效管理多个谷歌账号?

您的业务活动需要多个 Gmail 帐户吗&#xff1f;出海畅游&#xff0c;Gmail账号是少不了的工具之一&#xff0c;可以关联到Twitter、Facebook、Youtube、Chatgpt等等平台&#xff0c;可以说是海外网络的“万能锁”。但是大家都知道&#xff0c;以上这些平台注册多账号如果产生关…

Codeforces Round 930 (Div. 2) ---- E. Pokémon Arena ---- 题解

E. Pokmon Arena&#xff1a; 题目大意&#xff1a; 思路解析&#xff1a; 可以想到的是&#xff0c;可以用最短路来解决这个问题&#xff0c;但是如果简单的建图的话&#xff0c;时间复杂度将会达到 O(n*n*m)&#xff0c;我们考虑怎么减少图中边的个数。 我们考虑一个颜色&…

C语言中的字符与字符串:魔法般的函数探险

前言 在C语言的世界里&#xff0c;字符和字符串是两个不可或缺的元素&#xff0c;它们像是魔法般的存在&#xff0c;让文字与代码交织出无限可能。而在这个世界里&#xff0c;有一批特殊的函数&#xff0c;它们如同探险家&#xff0c;引领我们深入字符与字符串的秘境&#xff0…

探索GlassWire:网络安全与流量监控软件

名人说&#xff1a;东边日出西边雨&#xff0c;道是无晴却有晴。——刘禹锡 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 一、软件介绍1、GlassWire&#xff08;免费版本&#xff09;2、核心特点 二、下载安装①…

想拿高薪?云计算或许是你的跳板!

随着科技的不断进步&#xff0c;云计算作为一项重要的技术趋势&#xff0c;正引领着整个行业的快速发展。越来越多的人开始关注云计算领域&#xff0c;希望通过学习和掌握这一技能来获得更高的薪资。那么&#xff0c;为什么选择云计算作为职业发展方向&#xff1f;学习云计算又…

sharding‐jdbc之分库分表(mysql主从同步的数据库安装和使用)

水平分表 创建基础工程.. 引入sharding‐jdbc的maven依赖包 注意需要数据库连接池等依赖 <dependency><groupId>org.apache.shardingsphere</groupId><artifactId>sharding-jdbc-spring-boot-starter</artifactId><version>4.0.0-RC1&l…

【pycharm】在debug循环时,如何快速debug到指定循环次数

【pycharm】在debug循环时&#xff0c;如何快速debug到指定循环次数 【先赞后看养成习惯】求关注收藏点赞&#x1f600; 在 PyCharm 中&#xff0c;可以使用条件断点来实现在特定循环次数后停止调试。这可以通过在断点处右键单击&#xff0c;然后选择 “Add Breakpoint” -&g…

ES6学习(五)-- Module 语法

文章目录 Module 语法1.1 痛点介绍(1) 异步加载(2) 私密(3) 重名(4) 依赖 1.2 解决方法(1) 解决异步加载问题(2) 解决私密问题(3) 重名解决方法(4) 解决依赖问题 1.3 模块化使用案例 Module 语法 之前js 出现的某些痛点&#xff1a; 在script 中引入的变量名不可以重复&#…