Java中 判断集合中的元素相等的依据 详细解析

2023-11-04

我们经常使用的集合如ArrayList,LinkedList,Vector,
**你在调用contains()方法的时候, 或者是你在根据对象移除元素 remove(Object o) 你知道他们是如何判断集合中的元素是否
是相等的吗**?
接下来我们跟着源码去详细探究一下
数据数据结构不同判断的依据就不同,我们先来看一下List类的判断依据.

先简单的了解一下
List类 : 有序,可以有重复元素。

ArrayList 底层是一个对象数组
private transient Object[] elementData;
LinkedList 属于链式数据结构,底层用的是一个Node类的节点,包括指针域和数据域.

private static class Node {
E item;
Node next;
Node prev;

    Node(Node<E> prev, E element, Node<E> next) {
        this.item = element;
        this.next = next;
        this.prev = prev;
    }
}

ArrayList LinkedList他们都是线程不同步的 Vector非常类似ArrayList,但是Vector是同步的。, ArrayList LinkedList多线程访问会抛出 ConcurrentModificationException。如果想使他们线程同步的可以使用 Collections.synchronizedList 方法将该集合“包装”起来

回归正题

我们想知道他们如何判断集合元素是否相等,我们应该想到的是contains(Object o)方法,接下来我们看一下contains(Object o)方法

  public boolean contains(Object o) {
        return indexOf(o) >= 0;
    }

他的方法内部调用了indexOf(o)这个方法,我们继续追踪看一下indexOf(o)方法

   public int indexOf(Object o) {
        if (o == null) {
            for (int i = 0; i < size; i++)
                if (elementData[i]==null)
                    return i;
        } else {
            for (int i = 0; i < size; i++)
                if (o.equals(elementData[i]))
                    return i;
        }
        return -1;
    }

看到这里我们应该能明白了 先判断要查找的元素是否为空,不为空的话就调用equals方法.由此我们得到一个结论
List类中判断元素是否相等依赖的是equals方法.

set类 : 无序,不允许重复

HashSet :
此实现不是同步的
我们知道HashSet它不允许出现重复元素,他是如何保证元素唯一的呢,我们应该首先想到的是看他的add()方法
如下

public boolean add(E e) {
return map.put(e, PRESENT)==null;
}

这里出现了一个map我们找找看看他是什么

我们在上面看到了他的定义

 private transient HashMap<E,Object> map;

现在我们知道了HashSet的内部其实是一个HashMap来维护的,众所周知HashMap的键是不允许有相同的,不用说HashMap的键就是HashSet的值,接下来我们只需要知道HashMap的键是如何保证唯一的就行了

我们就要追踪HashMap的添加元素方法 put(K key, V value)

public V put(K key, V value) {
        if (table == EMPTY_TABLE) {
            inflateTable(threshold);
        }
        if (key == null)
            return putForNullKey(value);
        int hash = hash(key);
        int i = indexFor(hash, table.length);
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }

虽然有点麻烦我们只需要仔细看看 一定可以看明白 抓住最重要的一句

e.hash == hash && ((k = e.key) == key || key.equals(k))

现在我们也知道了HashSet 和HaspMap 保证元素唯一的办法是 先比较两个元素的哈希值,如果哈希值相等,在比较元素的地址是否相同,或者调用两个元素的equals方法如果哈希值不同,就根本不用在比较了.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java中 判断集合中的元素相等的依据 详细解析 的相关文章

  • 获取文件的锁

    我想在对特定文件开始 threo read 时获取文件上的锁定 以便其他应用程序无法读取已锁定的文件并希望在线程终止时释放锁定文件 您可以获得一个FileLock https docs oracle com javase 8 docs ap
  • 带有 Android 支持库 v7 的 Maven Android 插件

    我使用 maven android plugin 构建我的 android 应用程序 它依赖于 android 支持库 v4 和 v7 由于我没有找到如何从developer android com下载整个sdk 因此我无法使用maven
  • 使用 WebDriver 单击新打开的选项卡中的链接

    有人可以在这种情况下帮助我吗 场景是 有一个网页 我仅在新选项卡中打开所有指定的链接 现在我尝试单击新打开的选项卡中的任何一个链接 在下面尝试过 但它仅单击主 第一个选项卡中的一个链接 而不是在新选项卡中 new Actions drive
  • 如何在 Openfire 中使用 smack

    你好 我计划开发一个可以连接到 gtalk facebook 等的聊天客户端 我决定将 smack API 与 openfire 一起使用 但我需要很少的指导来了解如何将它与 openfire 服务器一起使用 openfire 是否提供了基
  • 当路径的点超出视野时,Android Canvas 不会绘制路径

    我在绘制路径时遇到了 Android Canvas 的一些问题 我的情况是 我有一个相对布局工作 如地图视图 不使用 google api 或类似的东西 我必须在该视图上绘制一条路径 canvas drawPath polyPath bor
  • 文本在指定长度后分割,但不要使用 grails 打断单词

    我有一个长字符串 需要将其解析为长度不超过 50 个字符的字符串数组 对我来说 棘手的部分是确保正则表达式找到 50 个字符之前的最后一个空格 以便在字符串之间进行彻底的分隔 因为我不希望单词被切断 public List
  • 在 Struts 2 中传递 URL 参数而不使用查询字符串

    我想使用类似的 URL host ActionName 123 abc 而不是像这样传递查询字符串 host ActionName parm1 123 parm2 abc 我怎样才能在 Struts 2 中做到这一点 我按照下面的方法做了
  • FileNotFoundException - Struts2 文件上传

    Strange FileNotFoundException使用Struts2上传文件时 这是 JSP 的一部分
  • 如何在java Spring Boot中实现通用服务类?

    我有许多具有重复代码的服务 我想知道如何实现通用服务 以便我的所有服务都可以扩展它 服务接口示例 重复代码 Service public interface IUserService List
  • Android蓝牙java.io.IOException:bt套接字已关闭,读取返回:-1

    我正在尝试编写一个代码 仅连接到运行 Android 5 0 KitKat 的设备上的 目前 唯一配对的设备 无论我尝试了多少方法 我仍然会收到此错误 这是我尝试过的最后一个代码 它似乎完成了我看到人们报告为成功的所有事情 有人能指出我做错
  • 如何通过注解用try-catch包装方法?

    如果应该在方法调用中忽略异常 则可以编写以下内容 public void addEntryIfPresent String key Dto dto try Map
  • Eclipse - 安装新的 JRE (Java SE 8 1.8.0)

    我正在尝试安装 Java 8 到目前为止我所做的 安装最新版本的 Eclipse 下载并安装 Java SE 运行时环境 8http www oracle com technetwork java javase downloads jre8
  • Java、Spring:使用 Mockito 测试 DAO 的 DataAccessException

    我正在尝试增加测试覆盖率 所以我想知道 您将如何测试 DAO 中抛出的 DataAccessExceptions 例如在一个简单的 findAll 方法中 该方法仅返回数据源中的所有数据 就我而言 我使用 Spring JdbcTempla
  • JAVA中遍历JSON数据

    我是 JSON 新手 我使用 HTTPUrlConnections 并在 JAVA 程序中获得一些响应 响应数据将类似于 data id 1 userId 1 name ABC modified 2014 12 04 created 201
  • Play.application() 的替代方案是什么

    我是 Play 框架的新手 我想读取conf文件夹中的一个文件 所以我用了Play application classloader getResources Data json nextElement getFile 但我知道 play P
  • 使用Java绘制维恩图

    我正在尝试根据给定的布尔方程绘制维恩图 例如 a AND b AND c我想在 Android 手机上执行此操作 因此我需要找到一种使用 Java 来执行此操作的方法 我找到了一个完美的小部件 它可以完成我在这方面寻找的一切布尔代数计算器
  • 如何从 Ant 启动聚合 jetty-server JAR?

    背景 免责声明 I have veryJava 经验很少 我们之前在 Ant 构建期间使用了 Jetty 6 的包装版本来处理按需静态内容 JS CSS 图像 HTML 因此我们可以使用 PhantomJS 针对 HTTP 托管环境运行单元
  • 我可以限制分布式应用程序发出的请求吗?

    我的应用程序发出 Web 服务请求 提供商处理的请求有最大速率 因此我需要限制它们 当应用程序在单个服务器上运行时 我曾经在应用程序级别执行此操作 一个对象跟踪到目前为止已发出的请求数量 并在当前请求超出允许的最大负载时等待 现在 我们正在
  • 使用 Java https 上传到 Imgur v3 错误

    我目前正在尝试使用他们当前的 API v3 上传到 imgur 但是我不断收到错误 错误 javax net ssl SSLException 证书中的主机名不匹配 api imgur com imgur com OR imgur com
  • ECDH使用Android KeyStore生成私钥

    我正在尝试使用 Android KeyStore Provider 生成的私有文件在 Android 中实现 ECDH public byte ecdh PublicKey otherPubKey throws Exception try

随机推荐

  • 控制算法之PID算法

    控制算法之PID算法 从入门到理解到应用 一发入魂 云 社区 腾讯云 tencent com
  • 数据库基础(面试常见题)

    数据库基础 面试常见题 一 数据库基础 1 数据抽象 物理抽象 概念抽象 视图级抽象 内模式 模式 外模式2 SQL语言包括数据定义 数据操纵 Data Manipulation 数据控制 Data Control 数据定义 Create
  • dedecms单独调用指定文章

    dede arclist idlist 指定ID limit 0 1 a href field title a dede arclist
  • 过滤器Filter,登陆验证,过滤敏感词,动态代理,Listener

    Filter 过滤器 概念 生活中的过滤器 净水器 空气净化器 土匪 web中的过滤器 当访问服务器的资源时 过滤器可以将请求拦截下来 完成一些特殊的功能 过滤器的作用 一般用于完成通用的操作 如 登录验证 统一编码处理 敏感字符过滤 快速
  • 前端npm和yarn更换国内淘宝镜像

    由于npm和yarn自带镜像是国外的 下载各种包比较慢 针对国内开发的小伙伴 如果没有科学上网的话 通常都会换一下镜像源 让开发下载各种包飞起来 以下是配置国内 淘宝镜像 提升下载速度的具体方法 赶紧收藏起来吧 关注 技术宅小Y 获取更多新
  • 如何调试JavaScript代码

    1 通过alert 来查看程序中的变量 由此也可以推断出程序跑到哪里就报错 用法 alert 1 弹出窗口显示1 var a 2 alert a a 弹出窗口显示a 2 2 添加debugger来调试javaScript 比较推荐这个 实用
  • PCB走线宽度

    结论 1A电流 至少10mil 建议15mil 2A电流 至少30mil 建议50mil 3A电流 至少60mil 建议100mil 大于3A 建议采用铺铜或开窗的形式 小于10mil线宽 建议电流小于0 1A
  • 如果有一条告警流量你会怎么分析,请详细说明?

    先要判断攻击有没有成功 是攻击成功的告警 还是攻击不成功但是真实的攻击 看规则的告警的名称 分析攻击源IP和目的IP 如果攻击源IP是内网的话 则可能为有关键特征的业务系统 被判为恶意攻击 内网可能沦陷 已被入侵 可能是设备使用盗版软件或者
  • Yolov5的安装配置与使用

    文章目录 一 下载Yolov5 1 下载Yolov5源码 2 下载Yolov5预训练模型 二 安装Yolov5 三 测试Yolov5 1 Img图片测试 2 Video视频测试 3 摄像头测试 三 小结 四 参考链接 在下载配置Yolov5
  • Echarts 实现两个图表联动

    init obj pageSource var that this console log obj pageSource this chart this echarts init document getElementById this i
  • 使用C++ Eigen库求解线性方程组Ax=b

    Eigen http eigen tuxfamily org 是常用的 C 矩阵运算库 具有很高的运算效率 大部分 需要在 C 中使用矩阵运算的库 都会选用 Eigen 作为基本代数库 例如 Google Tensorflow Google
  • 批量读取csv文件指定列

    目录 一 算法原理 二 代码实现 三 注意事项 一 算法原理 在读取csv文件进行点云处理的时候 常常需要跳过表头 并且进行批量读取 本代码 将每行数据记录为一个数组 并将多个csv文件合并记录 在使用中 需要自己修改想要提取的列数以及定义
  • FM33LG0XX-16位基本定时器

    FM33LG0包含1个16位基本定时器 基本定时器包含一个16bit自动重载计数器及一个可编程预分频器 基本定时器主要用来产生系统时基 也可以产生触发事件来驱动ADC采样 测试代码如下 void BSTIM Init uint16 t pr
  • 【转载收藏】Unity预计算实时GI

    初步介绍 新年假期结束了 想不想掌握一个新技能迎接全新的一年呢 不妨来阅读一下Unity预计算实时GI系列文章 本文是该系列的第一篇 在Unity中有两种区别很大的技术被用于计算全局光照GI或光源反射 它们就是烘焙全局光照 Baked GI
  • 【一文搞懂】FD_SET的使用

    阅读大概需要十分钟 绝对干货 看完还没搞懂你找我 随便查一下 可以看到对FD SET的说明如下 一个long类型的数组 提供给select 机制使用的一种数据结构 主要功能是建立联系 其中每一个数组元素都能与任意一个打开的句柄 socket
  • 回溯法(基础版)

    能进则进 不能进则换 不能换则退 退一步海阔天空 文章目录 算法适用问题 算法思想步骤 基础题目 A 装载问题 B 0 1背包问题 C N皇后问题 D 涂色问题 算法适用问题 搜索问题 求解的个数 最优解问题 算法思想步骤 深度优先搜索 定
  • js实现圆型的进度条

    一次项目需求中需要实现一个圆形的进度条 就参考了网上的一些资料做了一个demo 具体代码如下
  • Java线程池七大参数详解和配置

    目录 一 corePoolSize核心线程数 二 maximunPoolSize最大线程数 三 keepAliveTime空闲线程存活时间 四 unit空闲线程存活时间的单位 五 workQueue线程工作队列 1 ArrayBlockin
  • Mac如何读写NTFS硬盘,NTFSTool让Mac也可以轻松读写NTFS硬盘

    在了解Mac如何读写NTFS格式硬盘前 我们应该先了解什么是NTFS硬盘 以及Mac为什么不能对NTFS硬盘进行读写 一 什么是NTFS硬盘 NTFS格式硬盘最早出现于1993年的win NT操作系统中 作为一款日志文件系统 除了可以对硬盘
  • Java中 判断集合中的元素相等的依据 详细解析

    我们经常使用的集合如ArrayList LinkedList Vector 你在调用contains 方法的时候 或者是你在根据对象移除元素 remove Object o 你知道他们是如何判断集合中的元素是否 是相等的吗 接下来我们跟着源