Java容器使用注意点
前置:问题
- 判空
- 集合转map
- 集合遍历
- 集合去重
- 集合转数组
- 数组转集合
一:集合判空
《阿里巴巴 Java 开发手册》的描述如下:
判断所有集合内部的元素是否为空,使用 isEmpty() 方法,而不是 size()==0 的方式。
我们在开发中也常用Spring提供的CollectionUtil.isEmpty(list)
// ConcurrentHashMap 的 size() 方法和 isEmpty() 方法的源码。
public int size() {long n = sumCount();return ((n < 0L) ? 0 :(n > (long)Integer.MAX_VALUE) ? Integer.MAX_VALUE :(int)n);
}
final long sumCount() {CounterCell[] as = counterCells; CounterCell a;long sum = baseCount;if (as != null) {for (int i = 0; i < as.length; ++i) {if ((a = as[i]) != null)sum += a.value;}}return sum;
}
public boolean isEmpty() {return sumCount() <= 0L; // ignore transient negative values
}
Spring中的源码
// 判null+判内容
public static boolean isEmpty(@Nullable Collection<?> collection) {return (collection == null || collection.isEmpty());}
Spring底层是直接使用isEmpty进行判空的。
这是因为 isEmpty() 方法的可读性更好,并且时间复杂度为 O(1)。
绝大部分我们使用的集合的 size() 方法的时间复杂度也是 O(1),不过,也有很多复杂度不是 O(1) 的,比如 java.util.concurrent 包下的某些集合(ConcurrentLinkedQueue\ConcurrentHashMap…)出于时间复杂度的考虑
二:集合转Map
《阿里巴巴 Java 开发手册》的描述如下:
在使用 java.util.stream.Collectors 类的 toMap() 方法转为 Map 集合时,一定要注意当 value 为 null 时会抛 NPE 异常。
class Dog {private String id;private String sex;
}List<Dog> list = new ArrayList<>();
list.add(new Dog("1212121","公"));
// value为null值,会报npe
list.add(new Dog("435",null));
// 空指针异常
list.stream().collect(Collectors.toMap(Dog::getId, Dog::getSex));
异常原因

- value判空

集合遍历
《阿里巴巴 Java 开发手册》的描述如下:
不要在 foreach 循环里进行元素的 remove/add 操作(这个问题我踩过坑,和你想删的东西绝对不一样)。remove 元素请使用 Iterator 方式,如果并发操作,需要对 Iterator 对象加锁。
通过反编译你会发现 foreach 语法底层其实还是依赖 Iterator 。不过, remove/add 操作直接调用的是集合自己的方法,而不是 Iterator 的 remove/add方法
这就导致 Iterator 莫名其妙地发现自己有元素被 remove/add ,然后,它就会抛出一个 ConcurrentModificationException 来提示用户发生了并发修改异常。这就是单线程状态下产生的 fail-fast 机制。
Java8之后使用removeIf
List<Integer> list = new ArrayList<>();
for (int i = 1; i <= 10; ++i) {list.add(i);
}
// 这个蛮好用的
list.removeIf(filter -> filter % 2 == 0); /* 删除list中的所有偶数 */
System.out.println(list); /* [1, 3, 5, 7, 9] */
集合去重
《阿里巴巴 Java 开发手册》的描述如下:
可以利用 Set 元素唯一的特性,可以快速对一个集合进行去重操作,避免使用 List 的 contains() 进行遍历去重或者判断包含操作。
// Set 去重代码示例// 无hash冲突时时间复杂度O(1)
public static <T> Set<T> removeDuplicateBySet(List<T> data) {if (CollectionUtils.isEmpty(data)) {return new HashSet<>();}return new HashSet<>(data);
}// List 去重代码示例//时间复杂度O(n) ,跟进去看contains方法就可以看出来
public static <T> List<T> removeDuplicateByList(List<T> data) {if (CollectionUtils.isEmpty(data)) {return new ArrayList<>();}List<T> result = new ArrayList<>(data.size());for (T current : data) {if (!result.contains(current)) {result.add(current);}}return result;
}// testMyList<Integer> integers = Arrays.asList(1, 1, 1, 12, 32, 32, 3245, 3123, 6, 6);// 推荐去重方式HashSet<Integer> integers1 = new HashSet<>(integers);System.out.println(JSON.toJSONString(integers1));
集合转数组
《阿里巴巴 Java 开发手册》的描述如下:
使用集合转数组的方法,必须使用集合的 toArray(T[] array),传入的是类型完全一致、长度为 0 的空数组。
toArray(T[] array) 方法的参数是一个泛型数组,如果 toArray 方法中没有传递任何参数的话返回的是 Object类 型数组。
String [] s= new String[]{"dog", "lazy", "a", "over", "jumps", "fox", "brown", "quick", "A"
};
List<String> list = Arrays.asList(s);
Collections.reverse(list);
//没有指定类型的话会报错
s=list.toArray(new String[0]);
由于 JVM 优化,new String[0]作为Collection.toArray()方法的参数现在使用更好,new String[0]就是起一个模板的作用,指定了返回数组的类型,0 是为了节省空间,因为它只是为了说明返回的类型。详见:https://shipilev.net/blog/2016/arrays-wisdom-ancients/
数组转集合
《阿里巴巴 Java 开发手册》的描述如下:
使用工具类 Arrays.asList() 把数组转换成集合时,不能使用其修改集合相关的方法, 它的 add/remove/clear 方法会抛出 UnsupportedOperationException 异常。
Arrays.asList()在平时开发中还是比较常见的,我们可以使用它将一个数组转换为一个 List 集合。
String[] myArray = {"Apple", "Banana", "Orange"};
List<String> myList = Arrays.asList(myArray);
//上面两个语句等价于下面一条语句
List<String> myList = Arrays.asList("Apple","Banana", "Orange");
JDK源码
/***返回由指定数组支持的固定大小的列表。此方法作为基于数组和基于集合的API之间的桥梁,* 与 Collection.toArray()结合使用。返回的List是可序列化并实现RandomAccess接口。*/
public static <T> List<T> asList(T... a) {return new ArrayList<>(a);
}
相关文章:
Java容器使用注意点
前置:问题 判空集合转map集合遍历集合去重集合转数组数组转集合 一:集合判空 《阿里巴巴 Java 开发手册》的描述如下: 判断所有集合内部的元素是否为空,使用 isEmpty() 方法,而不是 size()0 的方式。 我们在开发中也…...
密文题解(图论+字典树)
题目大意 有一段长度为nnn的密文,密文的每一位都可以用一个非负整数来描述,并且每一位都有一个权值aia_iai。你可以操作任意多次,每次操作可以选择任意一段密文,花费选择的所有位上权值的异或和的代价获得这段密文每一位的异或…...
Baumer工业相机堡盟工业相机如何通过BGAPISDK里的工具函数来计算工业相机的实时帧率(C#)
Baumer工业相机堡盟工业相机如何通过BGAPISDK里函数来计算相机的实时帧率(C#)Baumer工业相机Baumer工业相机的帧率的技术背景Baumer工业相机的帧率计算方式在BufferEvent声明显示FrameID设计显示帧率的函数Baumer工业相机通过BGAPI SDK计算帧率的优势B…...
数据结构与常量(Java)
目录 1.字面常量 2. 数据类型 3. 变量 3.1 变量概念 3.2 语法格式 补充:变量 int long short double和float char boolean byte 4.类型转换 类型提升小结 5. 字符串类型 1. int 转成 String 2. String 转成 int 1.字面常量 类似System.Out.p…...
【LeetCode】剑指 Offer 54. 二叉搜索树的第k大节点 p269 -- Java Version
题目链接:https://leetcode.cn/problems/er-cha-sou-suo-shu-de-di-kda-jie-dian-lcof/ 1. 题目介绍( 54. 二叉搜索树的第k大节点) 给定一棵二叉搜索树,请找出其中第 k 大的节点的值。 【测试用例】: 示例 1: 示例2&…...
[工具类] post请求 获取request对象, 获取request的请求体(body)参数
目录 引言: 1. 获取request对象的几种常用方式 -> 1.1 获取请求对象 通过请求上下文对象 获取信息[推荐] -> 1.2 在controller层直接获取[不推荐 侵害性太强] -> 1.3 interceptor中获取[部分业务中使用] -> 1.4 request常用api简介 2. 获取request的body的工具…...
Golang 多版本安装小工具G
voidint制作的Golang版本安装管理,非常好用。想装就装,想换版本就换版本 除了一些使用go install的场景可能有不兼容,主要是安装了工具有时候不能直接用。 GitHub - voidint/g: Golang Version Manager 使用方式很简单&a…...
day29—选择题
文章目录1.HashSet子类依靠什么方法区分重复元素(C)2.以下代码在编译和运行过程中会出现什么情况(A)3.有这么一段程序,执行的结果是(C)1.HashSet子类依靠什么方法区分重复元素(C&…...
day8 互斥锁/读写锁的概念及使用、死锁的避免
目录 互斥锁的概念和使用 线程通信 - 互斥 互斥锁的创建和销毁 互斥锁的创建 互斥锁的销毁 互斥锁的使用 申请锁 释放锁 互斥锁的概念和使用 线程通信 - 互斥 临界资源: 一次只允许一个任务(进程、线程)访问的共享资源;…...
2023-04-13 monetdb-str类型变长存储-分析
摘要: monetdb的列的基本抽象是BAT,但是对于列数据的存储方式, 对于固定长度和不固定长度,使用了不同的存储方式。 固定长度的数据比如int,int64之类的, 直接存储在了数据tail文件。 但是对于不固定长度比如string, 则使用另外一个独立的theap文件存储, tail文件仅保留对于…...
011:Mapbox GL两种方式隐藏logo和版权,个性化版权的声明
第011个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+mapbox中用两种方式隐藏logo和版权,并个性化版权的声明 。 直接复制下面的 vue+mapbox源代码,操作2分钟即可运行实现效果 文章目录 示例效果配置方式示例源代码(共91行)相关API参考:专栏目标示例效果 配置方式…...
结合PCA降维的DBSCAN聚类方法(附Python代码)
目录 前言介绍: 1、PCA降维: (1)概念解释: (2)实现步骤: (3)优劣相关: 2、DBSCAN聚类: (1)概念解释&a…...
限流:计数器、漏桶、令牌桶 三大算法的原理与实战(史上最全)
限流 限流是面试中的常见的面试题(尤其是大厂面试、高P面试) 注:本文以 PDF 持续更新,最新尼恩 架构笔记、面试题 的PDF文件,请到文末《技术自由圈》公号获取 为什么要限流 简单来说: 限流在很多场景中用来…...
Redis用于全局ID生成器、分布式锁的解决方案
全局ID生成器 每个店铺都可以发布优惠卷 当用户抢购时,就会生成订单并保存到tb_voucher_order这张表中,而订单表如果使用数据库自增id就存在一些问题: 1.id的规律性太明显 2.受单表数据量的限制 全局ID生成器,是一种在分布式系…...
OpenTex 企业内容管理平台
OpenText 企业内容管理平台 将内容服务与领先应用程序集成,弥合内容孤岛、加快信息流并扩大治理 什么是内容服务集成? 内容服务集成通过将内容管理平台与处于流程核心的独立应用程序和系统连接起来,支持并扩展了 ECM 的传统优势。 最好的内…...
【0基础学爬虫】爬虫基础之数据存储
大数据时代,各行各业对数据采集的需求日益增多,网络爬虫的运用也更为广泛,越来越多的人开始学习网络爬虫这项技术,K哥爬虫此前已经推出不少爬虫进阶、逆向相关文章,为实现从易到难全方位覆盖,特设【0基础学…...
Redis与本地缓存组合使用(IT枫斗者)
Redis与本地缓存组合使用 前言 我们开发中经常用到Redis作为缓存,将高频数据放在Redis中能够提高业务性能,降低MySQL等关系型数据库压力,甚至一些系统使用Redis进行数据持久化,Redis松散的文档结构非常适合业务系统开发…...
手把手教你学习IEC104协议和编程实现 十 故障事件与复位进程
故障事件 目的 在IEC104普遍应用之前,据我了解多个协议,再综合自动化协议中,有这么一个概念叫“事故追忆”,意思是当变电站出现事故的时候,不但要记录事故的时间,还需记录事故前后模拟量的数据,从而能从一定程度上分析事故产生的原因,这个模拟量就是和今天讲解的故障…...
浅析分布式理论的CAP
大家好,我是易安! 今天让我们来聚焦于分布式系统架构中的重要理论——CAP理论。在分布式系统中,可用性和数据一致性是两个至关重要的因素,而CAP理论就是在这两者之间提供了一种权衡的原则,帮助我们在设计分布式系统时进…...
使用 TensorFlow 构建机器学习项目:6~10
原文:Building Machine Learning Projects with TensorFlow 协议:CC BY-NC-SA 4.0 译者:飞龙 本文来自【ApacheCN 深度学习 译文集】,采用译后编辑(MTPE)流程来尽可能提升效率。 不要担心自己的形象&#x…...
3步掌握VectorBT:Python量化交易框架的终极指南
3步掌握VectorBT:Python量化交易框架的终极指南 【免费下载链接】vectorbt Find your trading edge, using the fastest engine for backtesting, algorithmic trading, and research. 项目地址: https://gitcode.com/gh_mirrors/ve/vectorbt 在量化交易的世…...
【手把手教学】Tesseract-OCR图片文字识别从安装到实战
1. Tesseract-OCR简介与安装准备 第一次接触图片文字识别技术时,我和很多人一样觉得这是个遥不可及的黑科技。直到发现了Tesseract-OCR这个开源工具,才发现原来OCR技术可以如此亲民。Tesseract最初由HP实验室开发,后来由Google接手维护&#…...
Arduino轻量级协作式任务调度库Jobber详解
1. Jobber库概述:面向Arduino的轻量级协作式任务调度框架Jobber是一个专为资源受限嵌入式平台(尤其是Arduino系列MCU)设计的协作式任务调度库,其核心目标是提供一种“模拟多线程”的编程模型,使开发者能够以接近线程的…...
STM32环境监测系统在烟花爆竹仓库的应用
1. 项目概述与背景烟花爆竹作为一种特殊商品,其存储环境的安全管理一直是行业痛点。传统的人工巡检方式存在明显的滞后性——我曾亲眼见过一家小型烟花仓库因为夜间温湿度骤变而引发自燃,等值班人员发现时火势已难以控制。这个基于STM32的环境监测系统正…...
二叉树面试送分题|力扣101对称+226翻转(递归极简写法,手写无压力)
兄弟们!二叉树面试中,有两道“送分题”必须拿捏——力扣101.对称二叉树和力扣226.翻转二叉树。这两道题难度不高,核心都能用递归轻松解决,代码简洁、逻辑直观,新手练一遍就能记住,面试手写直接加分…...
Claude Code + PromptX 实战:如何让AI像你的最佳实习生一样写代码
Claude Code PromptX 实战:如何让AI像你的最佳实习生一样写代码 在软件开发领域,AI辅助编程已经从概念验证阶段迈入了实际生产力阶段。Claude Code与PromptX的组合,为开发者提供了一个强大的"虚拟实习生"——它不会抱怨加班&#…...
【等保三级Java系统合规落地指南】:20年安全架构师亲授7大关键改造步骤与避坑清单
第一章:等保三级Java系统合规落地的顶层认知与法律依据等保三级(GB/T 22239–2019《信息安全技术 网络安全等级保护基本要求》)并非单纯的技术加固任务,而是覆盖组织管理、制度建设、技术实施与持续运营的全生命周期合规工程。对J…...
三菱Q00/PLC与台达DTA温控器通讯案例 功能:通过三菱QJ71C24N模块与台达DTA温...
三菱Q00/PLC与台达DTA温控器通讯案例 功能:通过三菱QJ71C24N模块与台达DTA温控器进行modbus-rtu通讯,实现温度读取、实际输出率(%)读取,及温度的设定、和温控探头类型的设定,PLC本体232-COM口与电脑通讯&am…...
Vivo Xplay6专用降级刷机工具AFTool|支持1.15.1/1.16.6/1.16.14等多版本线刷|含教程+驱动+工具包
温馨提示:文末有联系方式【适用机型精准说明】 本工具包专为Vivo Xplay6(型号V317A/V317K)深度适配,非Xplay6机型(含其他Vivo手机)请勿购买——不同机型Bootloader锁机制与分区结构差异极大,强行…...
Python实战:用SymPy解常微分方程 vs 偏微分方程的5个关键差异
Python实战:用SymPy解常微分方程 vs 偏微分方程的5个关键差异 微分方程是数学建模的核心工具,而Python的SymPy库让符号计算变得触手可及。但当你真正在Jupyter Notebook中敲下dsolve()命令时,是否困惑过为什么有些方程秒出结果,有…...
