【Java 集合】Collections 空列表细节处理
问题
如下代码,虽然定义为非空 NonNull,但依然会返回空对象,导致调用侧被检测为空引用。
实际上不是Collections的问题是三目运算符返回了null对象。
import java.util.Collections;@NonNullprivate List<String> getInfo() {IccRecords iccRecords = mPhone.getIccRecords();if(iccRecords != null) {//省略逻辑String[] simSpdi = iccRecords.getServiceProviderDisplayInformation();return simSpdi != null ? Arrays.asList(simSpdi) : null; //根因是这里返回null}return Collections.EMPTY_LIST;}
源码案例
frameworks/opt/telephony/src/java/com/android/internal/telephony/cdnr/CarrierDisplayNameResolver.java
@NonNullprivate List<String> getEfSpdi() {for (int i = 0; i < mEf.size(); i++) {if (mEf.valueAt(i).getServiceProviderDisplayInformation() != null) {return mEf.valueAt(i).getServiceProviderDisplayInformation();}}return Collections.EMPTY_LIST;}@NonNullprivate String getEfSpn() {for (int i = 0; i < mEf.size(); i++) {if (!TextUtils.isEmpty(mEf.valueAt(i).getServiceProviderName())) {return mEf.valueAt(i).getServiceProviderName();}}return "";}@NonNullprivate List<OperatorPlmnInfo> getEfOpl() {for (int i = 0; i < mEf.size(); i++) {if (mEf.valueAt(i).getOperatorPlmnList() != null) {return mEf.valueAt(i).getOperatorPlmnList();}}return Collections.EMPTY_LIST;}@NonNullprivate List<PlmnNetworkName> getEfPnn() {for (int i = 0; i < mEf.size(); i++) {if (mEf.valueAt(i).getPlmnNetworkNameList() != null) {return mEf.valueAt(i).getPlmnNetworkNameList();}}return Collections.EMPTY_LIST;}
代码解析
注意Collection和Collections是不同的。
- libcore/ojluni/src/main/java/java/util/Collections.java 工具类
- libcore/ojluni/src/main/java/java/util/Collection.java 接口
Collections中定义了内部类EmptyList,在静态List常量EMPTY_LIST(immutable不可变列表)初始化时会new一个没有指定类型的EmptyList。
public class Collections {/*** The empty list (immutable). This list is serializable.** @see #emptyList()*/@SuppressWarnings("rawtypes")public static final List EMPTY_LIST = new EmptyList<>();/*** Returns an empty list (immutable). This list is serializable.** <p>This example illustrates the type-safe way to obtain an empty list:* <pre>* List<String> s = Collections.emptyList();* </pre>** @implNote* Implementations of this method need not create a separate {@code List}* object for each call. Using this method is likely to have comparable* cost to using the like-named field. (Unlike this method, the field does* not provide type safety.)** @param <T> type of elements, if there were any, in the list* @return an empty immutable list** @see #EMPTY_LIST* @since 1.5*/@SuppressWarnings("unchecked")public static final <T> List<T> emptyList() {return (List<T>) EMPTY_LIST;}/*** @serial include*/private static class EmptyList<E>extends AbstractList<E>implements RandomAccess, Serializable {@java.io.Serialprivate static final long serialVersionUID = 8842843931221139166L;public Iterator<E> iterator() {return emptyIterator();}public ListIterator<E> listIterator() {return emptyListIterator();}// Preserves singleton property@java.io.Serialprivate Object readResolve() {return EMPTY_LIST;}}}
解决方案
将 Collections.EMPTY_LIST 替换成 Collections.emptyList()。
虽然它们都可以用于表示一个空的不可变列表,但 Collections.emptyList()
是更优先的选择,因为它提供了类型安全性和更好的代码可读性。
附:Collections 源码
一些值得学习的语法,Android 扩展的排序跟Java 集合原生排序的实现差异
libcore/ojluni/src/main/java/java/util/Collections.java
import dalvik.system.VMRuntime;/*** This class consists exclusively of static methods that operate on or return* collections. It contains polymorphic algorithms that operate on* collections, "wrappers", which return a new collection backed by a* specified collection, and a few other odds and ends.** <p>The methods of this class all throw a {@code NullPointerException}* if the collections or class objects provided to them are null.** <p>The documentation for the polymorphic algorithms contained in this class* generally includes a brief description of the <i>implementation</i>. Such* descriptions should be regarded as <i>implementation notes</i>, rather than* parts of the <i>specification</i>. Implementors should feel free to* substitute other algorithms, so long as the specification itself is adhered* to. (For example, the algorithm used by {@code sort} does not have to be* a mergesort, but it does have to be <i>stable</i>.)** <p>The "destructive" algorithms contained in this class, that is, the* algorithms that modify the collection on which they operate, are specified* to throw {@code UnsupportedOperationException} if the collection does not* support the appropriate mutation primitive(s), such as the {@code set}* method. These algorithms may, but are not required to, throw this* exception if an invocation would have no effect on the collection. For* example, invoking the {@code sort} method on an unmodifiable list that is* already sorted may or may not throw {@code UnsupportedOperationException}.** <p>This class is a member of the* <a href="{@docRoot}/java.base/java/util/package-summary.html#CollectionsFramework">* Java Collections Framework</a>.** @author Josh Bloch* @author Neal Gafter* @see Collection* @see Set* @see List* @see Map* @since 1.2*/public class Collections {// Suppresses default constructor, ensuring non-instantiability.private Collections() {}// Algorithms// Android-added: List.sort() vs. Collections.sort() app compat.// Added a warning in the documentation.// Collections.sort() calls List.sort() for apps targeting API version >= 26// (Android Oreo) but the other way around for app targeting <= 25 (Nougat)./*** Sorts the specified list into ascending order, according to the* {@linkplain Comparable natural ordering} of its elements.* All elements in the list must implement the {@link Comparable}* interface. Furthermore, all elements in the list must be* <i>mutually comparable</i> (that is, {@code e1.compareTo(e2)}* must not throw a {@code ClassCastException} for any elements* {@code e1} and {@code e2} in the list).** <p>This sort is guaranteed to be <i>stable</i>: equal elements will* not be reordered as a result of the sort.** <p>The specified list must be modifiable, but need not be resizable.** @implNote* This implementation defers to the {@link List#sort(Comparator)}* method using the specified list and a {@code null} comparator.* Do not call this method from {@code List.sort()} since that can lead* to infinite recursion. Apps targeting APIs {@code <= 25} observe* backwards compatibility behavior where this method was implemented* on top of {@link List#toArray()}, {@link ListIterator#next()} and* {@link ListIterator#set(Object)}.** @param <T> the class of the objects in the list* @param list the list to be sorted.* @throws ClassCastException if the list contains elements that are not* <i>mutually comparable</i> (for example, strings and integers).* @throws UnsupportedOperationException if the specified list's* list-iterator does not support the {@code set} operation.* @throws IllegalArgumentException (optional) if the implementation* detects that the natural ordering of the list elements is* found to violate the {@link Comparable} contract* @see List#sort(Comparator)*/public static <T extends Comparable<? super T>> void sort(List<T> list) {// Android-changed: List.sort() vs. Collections.sort() app compat.// Call sort(list, null) here to be consistent with that method's// (changed on Android) behavior.// list.sort(null);sort(list, null);}}
相关文章:
【Java 集合】Collections 空列表细节处理
问题 如下代码,虽然定义为非空 NonNull,但依然会返回空对象,导致调用侧被检测为空引用。 实际上不是Collections的问题是三目运算符返回了null对象。 import java.util.Collections;NonNullprivate List<String> getInfo() {IccReco…...

大数据实验4-HBase
一、实验目的 阐述HBase在Hadoop体系结构中的角色;能够掌握HBase的安装和配置方法熟练使用HBase操作常用的Shell命令; 二、实验要求 学习HBase的安装步骤,并掌握HBase的基本操作命令的使用; 三、实验平台 操作系统࿱…...

deepin系统下载pnpm cnpm等报错
deepin系统下载pnpm cnpm等报错 npm ERR! request to https://registry.npm.taobao.org/pnpm failed, reason: certificate has expired 报错提示证书过期,执行以下命令 npm config set registry https://registry.npmmirror.com下载pnpm npm install pnpm -g查…...
#Js篇:JSON.stringify 和 JSON.parse用法和传参
JSON.stringify 和 JSON.parse 1. JSON.stringify JSON.stringify 方法将一个 JavaScript 对象或数组转换为 JSON 字符串。 基本用法 const obj { name: "Alice", age: 25 }; const jsonString JSON.stringify(obj); console.log(jsonString); // 输出: {"…...
c#通过网上AI大模型实现对话功能
目录 基础使用给大模型额外提供函数能力用Microsoft.Extensions.AI库实现用json格式回答 基础使用 https://siliconflow.cn/网站有些免费的大模型可以使用,去注册个账户,拿到apikey 引用 nuget Microsoft.Extensions.AI.OpenAI using Microsoft.Extensi…...

pymysql模块
1.pymysql基本使用 打开数据库连接,使用cursor()方法获取操作游标执行SQL语句 获取命令执行的查询结果 1.1 打开数据库连接 # 打开数据库连接 db pymysql.connect(host127.0.0.1,userroot,port3306,password"123",databasedb5) 1.2 使用cursor()方法获取操作游…...

WPF-模板和样式
在 WPF(Windows Presentation Foundation)中,模板是一种强大的机制,用于定义控件的外观。它允许你将控件的逻辑(功能)和外观(UI)分离开来。例如,一个按钮控件,…...

网络编程 day1.2~day2——TCP和UDP的通信基础(TCP)
笔记脑图 作业: 1、将虚拟机调整到桥接模式联网。 2、TCP客户端服务器实现一遍。 服务器 #include <stdio.h> #include <string.h> #include <myhead.h> #define IP "192.168.60.44" #define PORT 6666 #define BACKLOG 20 int mai…...
element ui table 每行不同状态
table 每行定义值 tableData: [ { name: ,type:,location:, ziduan:,createtype:,ziduanvalue:,checkAll:true,checkedCities: [空, null, str随机, int随机],isIndeterminate: true,table_id:single,downloaddisabled:true,deldisabled:true} ], table c…...
力扣--LRC 142.训练计划IV
题目 给定两个以 有序链表 形式记录的训练计划 l1、l2,分别记录了两套核心肌群训练项目编号,请合并这两个训练计划,按训练项目编号 升序 记录于链表并返回。 注意:新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&am…...

windows下,用CMake编译qt项目,出现错误By not providing “FindQt5.cmake“...
开发环境:windows10 qt5.14, 编译器msvc2017x64,CMake3.30; 现象: CMakeList文件里,如有find_package(Qt5 COMPONENTS Widgets REQUIRED) target_link_libraries(dis_lib PRIVATE Qt5::Widgets) 用CMak…...

【element-tiptap】Tiptap编辑器核心概念----结构篇
core-concepts 前言:这篇文章来介绍一下 Tiptap 编辑器的一些核心概念 (一)结构 1、 Schemas 定义文档组成方式。一个文档就是标题、段落以及其他的节点组成的一棵树。 每一个 ProseMirror 的文档都有一个与之相关联的 schema,…...
半导体工艺与制造篇3 离子注入
离子注入工艺 一般掺杂的杂质类别,包括:提供载流子的施主杂质和受主杂质;产生复合中心的重金属杂质 离子注入往往需要生成井well,其中井的定义:晶圆与杂质之间形成的扩散层或杂质与杂质之间形成的扩散层 离子注入的目的:用掺杂改…...

利用开源的低代码表单设计器FcDesigner高效管理和渲染复杂表单结构
FcDesigner 是一个强大的开源低代码表单设计器组件,支持快速拖拽生成表单。提供丰富的自定义及扩展功能,FcDesigner支持多语言环境,并允许开发者进行二次开发。通过将表单设计输出为JSON格式,再通过渲染器进行加载,实现…...
淘宝 NPM 镜像源
npm i vant/weapp -S --production npm config set registry https://registry.npmmirror.com 要在淘宝 NPM 镜像站下载项目或依赖,你可以按照以下步骤操作: 1. 设置淘宝 NPM 镜像源 首先,你需要设置淘宝 NPM 镜像源以加速下载。可以通过…...

i春秋-GetFlag(md5加密,字符串比较绕过)
练习平台地址 竞赛中心 题目描述 题目内容 你好,单身狗,这是一个迷你文件管理器,你可以登录和下载文件,甚至得到旗帜 点击登录 发现capture需要满足条件substr(md5(captcha), 0, 6)xxxxxx 编写python脚本破解验证码 import has…...

SpringBoot中设置超时30分钟自动删除元素的List和Map
简介 在 Spring Boot 中,你可以使用多种方法来实现自动删除超时元素的 List 或 Map。以下是两种常见的方式: 如果你需要简单的功能并且不介意引入外部依赖,可以选择 Guava Cache。如果你想要更灵活的控制,使用 Spring 的调度功能…...

入门车载以太网(6) -- XCP on Ethernet
目录 1.寻址方式 2.数据帧格式 3.特殊指令 4.使用实例 了解了SOME/IP之后,继续来看看车载以太网在汽车标定领域的应用。 在汽车标定领域XCP是非常重要的协议,咱们先来回顾下基础概念。 XCP全称Universal Measurement and Calibration Protocol&a…...

DAY4 网络编程(广播和多线程并发)
作业1: 1、将广播发送和接收端实现一遍,完成一个发送端发送信息,对应多个接收端接收信息实验。 send.c代码: #include <myhead.h> #define IP "192.168.61.255"//广播IP #define PORT 7777 int main(int argc, …...
C++个人复习(4)
C中为什么要引入make_shared,它有什么优点 1. 减少内存分配次数 使用 make_shared 时,内存分配只发生一次,它同时分配了对象和控制块(用于管理引用计数等信息)。而如果直接使用 new 创建对象并传递给 shared_ptr,则会…...

关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...

高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...

Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...

【LeetCode】算法详解#6 ---除自身以外数组的乘积
1.题目介绍 给定一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O…...

高考志愿填报管理系统---开发介绍
高考志愿填报管理系统是一款专为教育机构、学校和教师设计的学生信息管理和志愿填报辅助平台。系统基于Django框架开发,采用现代化的Web技术,为教育工作者提供高效、安全、便捷的学生管理解决方案。 ## 📋 系统概述 ### 🎯 系统定…...

2025-05-08-deepseek本地化部署
title: 2025-05-08-deepseek 本地化部署 tags: 深度学习 程序开发 2025-05-08-deepseek 本地化部署 参考博客 本地部署 DeepSeek:小白也能轻松搞定! 如何给本地部署的 DeepSeek 投喂数据,让他更懂你 [实验目的]:理解系统架构与原…...