详述HashSet类add方法(一)

学Simulink--决策规划场景实例:基于Simulink的智能车辆行为决策仿真 本文基于Simulink平台构建智能车辆变道决策仿真系统,采用MOBIL算法实现"决策-规划-执行"全流程。系统包含自车动力学模型、环境感知模块(含5%噪声)、决策控制器和轨迹规划模块,通过五次多项式实现平滑变道。仿真验证了三种典型工况:正常变道(成功率100%)、邻车拒绝让行和紧急避障,各项指标均满足要求(TTC>3s,横向加速度<2m/s²,决策周期<100ms)。文章详细介绍了建模步骤、核心算法实现和参数配置方法,并提出了强化学习、多车协同等优化方向。该模型为智能 阅读详情

我们知道,add方法可以用来向集合中添加元素,对于HashSet集合来说,不允许存储重复的元素,当我们存储元素的时候,集合会对添加进来的元素进行判断是否重复,首先我们对新加元素进行分析:
add方法源码:(jdk-11.0.4)

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

此时我们发现,返回值是一个布尔值,如果添加成功,则返回true,否则返回false,那么其中用到了put方法,其属于HashMap集合,用来将元素添加到HashMap中的Key,而我们知道,HashMap集合是Key和value一一对应的关系,也就是说key不允许重复,而此时显然我们不需要添加value,此时的value值是一个Object常量,put方法源码如下

	public V put(K key, V value) {
        return putVal(hash(key), key, value, false, true);
    }

此时其中用到了putVal和hash()方法:

	final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                   boolean evict) {
        Node<K,V>[] tab; Node<K,V> p; int n, i;
        if ((tab = table) == null || (n = tab.length) == 0)//table=null,tab=null,则(tab=table)==null为true
            n = (tab = resize()).length;//resize()方法直接为table返回newTab,resize()方法也返回newTab,所以,table和tab是一个对象,数组长度16
        if ((p = tab[i = (n - 1) & hash]) == null)//i = (n - 1) & hash 数组长度-1 & hash i是下表 tab[i -(n-1) & hash],因为此时只存储一个值,所以一定是null
            tab[i] = newNode(hash, key, value, null);//tab[i] i (n-1) & hash 为(n-1)&hash添加一个元素,因为数组是地址传递,所以table全局变量i也有值
        else {
            Node<K,V> e; K k;
            if (p.hash == hash &&
                ((k = p.key) == key || (key != null && key.equals(k))))
                e = p;
            else if (p instanceof TreeNode)
                e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
            else {
                for (int binCount = 0; ; ++binCount) {
                    if ((e = p.next) == null) {
                        p.next = newNode(hash, key, value, null);
                        if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
                            treeifyBin(tab, hash);
                        break;
                    }
                    if (e.hash == hash &&
                        ((k = e.key) == key || (key != null && key.equals(k))))
                        break;
                    p = e;
                }
            }
            if (e != null) { // existing mapping for key
                V oldValue = e.value;
                if (!onlyIfAbsent || oldValue == null)
                    e.value = value;
                afterNodeAccess(e);
                return oldValue;
            }
        }
        ++modCount;
        if (++size > threshold)
            resize();
        afterNodeInsertion(evict);
        return null;
    }

hash()方法

	static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

resize()方法:

final Node<K,V>[] resize() {
        Node<K,V>[] oldTab = table;
        int oldCap = (oldTab == null) ? 0 : oldTab.length;
        int oldThr = threshold;
        int newCap, newThr = 0;
        if (oldCap > 0) {
            if (oldCap >= MAXIMUM_CAPACITY) {
                threshold = Integer.MAX_VALUE;
                return oldTab;
            }
            else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY &&
                     oldCap >= DEFAULT_INITIAL_CAPACITY)
                newThr = oldThr << 1; // double threshold
        }
        else if (oldThr > 0) // initial capacity was placed in threshold
            newCap = oldThr;
        else {               // zero initial threshold signifies using defaults
            newCap = DEFAULT_INITIAL_CAPACITY;
            newThr = (int)(DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY);
        }
        if (newThr == 0) {
            float ft = (float)newCap * loadFactor;
            newThr = (newCap < MAXIMUM_CAPACITY && ft < (float)MAXIMUM_CAPACITY ?
                      (int)ft : Integer.MAX_VALUE);
        }
        threshold = newThr;
        @SuppressWarnings({"rawtypes","unchecked"})
        Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap];
        table = newTab;
        if (oldTab != null) {
            for (int j = 0; j < oldCap; ++j) {
                Node<K,V> e;
                if ((e = oldTab[j]) != null) {
                    oldTab[j] = null;
                    if (e.next == null)
                        newTab[e.hash & (newCap - 1)] = e;
                    else if (e instanceof TreeNode)
                        ((TreeNode<K,V>)e).split(this, newTab, j, oldCap);
                    else { // preserve order
                        Node<K,V> loHead = null, loTail = null;
                        Node<K,V> hiHead = null, hiTail = null;
                        Node<K,V> next;
                        do {
                            next = e.next;
                            if ((e.hash & oldCap) == 0) {
                                if (loTail == null)
                                    loHead = e;
                                else
                                    loTail.next = e;
                                loTail = e;
                            }
                            else {
                                if (hiTail == null)
                                    hiHead = e;
                                else
                                    hiTail.next = e;
                                hiTail = e;
                            }
                        } while ((e = next) != null);
                        if (loTail != null) {
                            loTail.next = null;
                            newTab[j] = loHead;
                        }
                        if (hiTail != null) {
                            hiTail.next = null;
                            newTab[j + oldCap] = hiHead;
                        }
                    }
                }
            }
        }
        return newTab;
    }

也就是说,当我们添加一个不存在的元素时, 首先调用HashSet类中的add方法,实质上是通过HashMap类型的全局变量map调用put方法。紧接着put方法调用putVal方法,执行putVal方法,table是一个全局变量,创建对象时并没有给table赋值,因此,tab = table = null,执行第一个if语句,调用resize方法。另tab等于resize方法的返回值。

在resize方法中,给全局变量table赋值为newTab,newTab初始数组长度为16,并且返回值也为newTab。又因为tab等于resize方法的返回值,所以第一个if语句执行结束后table和tab指向同一个地址,n = 16。

执行第二个if语句,第二个if语句的判断条件是将hash值与(n-1)做按位与运算,动态的找到数组的一个元素,判断是否为null。因为并未给数组tab赋值数组里的元素一定都为null,所以if语句的判断条件一定成立。if语句 tab[i] = newNode(hash, key, value, null);将传入的结点赋值给在if语句判断条件里找到的那个数组元素。

执行第三个也是最后一个if语句,返回null。因为putVal返回值为null,null = null,所以put方法的返回值为true,即add方法的返回值为true,添加成功。

【Python机器学习】零基础掌握TweedieRegressor广义线性回归模型 本次文章主要介绍了如何使用Tweedie回归模型预测电动汽车的实际续航里程。基于车速、气温和驾驶习惯等多种因素,模型能够准确地预测出电动汽车的续航里程,从而为生产商和消费者提供有用的信息。优点总结,Tweedie回归模型在处理具有多元性和高度散布的数据方面表现出色,特别适用于需要考虑多种影响因素的预测任务。优点名称对应描述说明多元性强可以同时处理多种类型和维度的数据高度可定制允许用户自定义损失函数和正则项对异常值鲁棒能够较好地处理数据中的异常值易于解释参数和预测结果都相对容易解释。 阅读详情

相关推荐

Chronos:学习时间序列的大语言模型(论文解读)

《Chronos:学习时间序列的大语言模型》论文翻译

qq_20144897的博客 9054

详述HashSet中add方法

一、HashSet中对象的创建 在分析HashSet的add方法的底层代码之前我们先要理解HashSet集合中的对象是如何创建的。 先创建一个JavaWeb工程,引入hashset的包,创建含有HashSet类的方法,然后就可以进入HashSet的底层代码: package hashset; import java.util.HashSet; public class Test { ...

x_j_k_jysg的博客 5466

GPT Researcher 的win docker安装攻略

github网址是:https://github.com/assafelovic/gpt-researcher/blob/master/README-zh_CN.md。使用 Docker 运行 AI-Researcher 项目的。因为docker安装方法不够清晰,因此写一个使用方法。打开设置——docker engine ,增加代码。如有其他问题,可提供错误截图或日志进一步排查!

weixin_43818488的博客 1125

HashSet中的add方法

1,对HashSet新建对象的分析 HashSet<String> set=new HashSet<String>(); 创建一个HashSet类的对象,new HashSet<String>()调用了HashSet中的无参构造方法 public HashSet(){ map=new HashMap<>(); } 实质又调用了HashMa...

YXX_decsdn的博客 2489

基于Active-HDL的HDL设计录入与仿真

作者:毛茏玮 / Saint 掘金:https://juejin.im/user/5aa1f89b6fb9a028bb18966a 微博:https://weibo.com/5458277467/profile?topnav=1&amp;wvr=6&amp;is_all=1 GitHub:github.com/saint-000 优快云: https://me.youkuaiyun.com/qq_4053...

一个会写代码的烤鸭 7782

【CQUT】从零开始龙芯杯-开始前的准备

不同级别的Cpu对于vivado综合的时间有较大影响,其中Cpu的单核、多核性能以及cache性能影响权重较高。因此,为了保证学习进度和效率,我们建议在Cpu不低于I5 12400的环境下进行学习。Vivado2023.2安装包约100GB,为了保证成功安装建议留出300GB硬盘空间。龙芯杯的许多资料被托管在gitee,你需要git指令将资料克隆到本地。指定用书:CPU设计实战 Loongarch版 作者:汪文祥、邢金璋。Cpu性能对比网站:https://www.cpu114.com/

weixin_73689971的博客 906

HashSet中add()方法的使用

HashSet 传入对象,怎么过滤 首先,我们知道所有的Set里面都套了一个Map,使用Map的Key存值,Value存放一个固定的Object,这是适配器模式。源码如下: public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable { static final long serialVersionUID =

Dream It Possible 5217

面试问题总结——关于YOLO系列(三)

接着上篇的的YOLO系列面试问题总结,加油,冲! 三.YOLOv3 1.YOLOv3主干网络BackBone——Darknet-53网络结构(因为有53个卷积层) (原论文中Darknet53的尺寸是在图片分类训练集上训练的,所以输入的图像尺寸是256x256,而在YOLOv3中输入尺寸是416×416)   ①上图中,Top-1 Accuracy和Top-5 Accuracy是指什么呢?区别在哪呢?   我们知道ImageNet有大概1000个分类,而模型预测某张图片时,会给出1000个按概率从高.

boss-dog 1万+

详述HashSet类中的add方法

详述HashSet类中的add方法 一、hashCode和toString方法 package add; import java.util.HashSet; public class Test { public static void main(String[] args) { HashSet<String> set = new HashSet<String&gt...

weixin_43964847的博客 1703

第150篇 激光雷达点云分割——地面分离、聚类分析和物体提取

本文介绍了点云分割的三种经典几何方法:RANSAC地面分离、欧式聚类和区域生长。RANSAC通过随机采样拟合平面实现地面分割,欧式聚类基于空间距离进行物体分割,区域生长则结合法线信息提升分割精度。文章对比了各种方法的优缺点,提供了参数选择建议,并指出实际项目中常组合使用这些方法。最后给出了面试应答技巧,强调几何方法速度快、可解释性强等优势,适合大多数机器人项目的实时需求。

郑伟强dev的专栏 192

第076篇:大涡模拟进阶

大涡模拟(Large Eddy Simulation, LES)是介于直接数值模拟(DNS)和雷诺平均方法(RANS)之间的重要湍流模拟方法。本文深入介绍动态Smagorinsky模型、尺度相似模型、WALE模型和隐式LES等高级亚格子模型。通过Python实现槽道湍流和圆柱绕流的LES求解器,详细展示近壁面处理、动态系数计算和亚格子应力建模技术。大涡模拟,亚格子模型,动态模型,Smagorinsky,WALE模型,尺度相似模型,近壁面处理,槽道湍流LES的核心思想是对Navier-Stokes方程进行空间

2401_87715305的博客 740

详述Java中HashSet类add方法(一)

import java.util.HashSet; public class Test { public static void main(String[] args) { HashSet<String> names = new HashSet<String>(); names.add("Jim"); } } 1、HashSet中add方法: ...

qq_46091702的博客 508

RK3588开发笔记-mipi csi接口imx415摄像头调试记录

摘要:本文详细介绍了RK3588开发板适配SONY IMX415 MIPI CSI摄像头的调试过程。从硬件环境准备(包括RK3588核心板、IMX415模块连接及测试工具)、软件环境配置(Linux 5.10内核、驱动状态确认),到设备树关键配置(MIPI链路、GPIO引脚、电源域等)都进行了详细说明。调试过程中通过dmesg日志、media-ctl拓扑分析等工具验证了摄像头驱动加载和图像采集功能。最终实现了800万像素高清图像采集,总结了硬件连接验证、信号完整性优化等关键经验,为类似MIPI摄像头调试提供

flypig has a dream! 882

详述:HashSet类add方法(一)

文章目录1、hash方法2、HashSet add方法(一) 1、hash方法 static final int hash(Object key) { int h; return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); } 当传入的对象key是一个null时,返回值...

核桃仁先生的博客 291

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

1、详述HashSet类add方法(一)

向集合中存储第一个元素,源代码解析 package sun6; import java.util.HashSet; public class Test2 { public static void main(String[] args) { HashSet<String> names = new HashSet<String>();//调用构造方法时,创建Hash...

深海潜蛟的博客 148

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

详述Java中HashSet类add方法(一)

创建HashSet集合: import java.util.HashSet; public class Test { public static void main(String[] args) { HashSet<String> names = new HashSet<String>(); names.add("Jim"); } } HashSet中的a...

FOREVER_GWC的博客 240

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

java——详述HashSet类add方法(一)

主程序: import java.util.HashSet; public class Test2 { public static void main(String[] args) { HashSet<String> names = new HashSet<String>();//调用构造方法时,创建HashMap集合对象 names.add("Jim");/...

qq_44687512的博客 235

Java中详述HashSet类add方法(一)

仅有唯一一个数据 import java.util.HashSet; public class Test2 { public static void main(String[] args) { HashSet<String> names = new HashSet<String>();//调用构造方法时,创建HashMap集合对象 names.ad...

zzu957的博客 297
上一篇: 详述ArrayList类的contains方法
下一篇: 详述HashSet类add方法(二)
CellIce
博客等级 码龄7年 2粉丝 68原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值