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中 判断集合中的元素相等的依据 详细解析 的相关文章

随机推荐

  • 控制算法之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 你知道他们是如何判断集合中的元素是否 是相等的吗 接下来我们跟着源