Arrays.asList(T...a)的使用问题

2023-10-29

我们经常会使用Arrays.asList来初始化一个列表List。例如

List<String> list = Arrays.asList("123","234");
或者
List<String> list = Arrays.<String>asList("123",234");

不过这里存在一个容易忽视的问题,Arrays.asList返回的是一个底层为大小固定的数组所构成的ArrayList。底层大小固定,所以任何对list的添加、删除或者运用到添加、删除操作的动作都无法进行。
例如上面的代码执行:

list.add("456");

就会报java.lang.UnsupportedOperationException异常。
更好一点的做法是将asList产生的列表当做参数传到另一个集合的构造器中来进行初始化,就不会有这样的限制。

List<String> list = new ArrayList<String>(Arrays.asList("123","234"));

不过为什么会有这样的限制呢。我们看Arrays.asList的源码
Arrays.java

public class Arrays{
     ...
     public static <T> List<T> asList(T... a) {
        return new ArrayList<>(a);
     }

    /**
     * 该静态内部类中并没有重写父类的add,remove等方法
     */
     private static class ArrayList<E> extends AbstractList<E>
        implements RandomAccess, java.io.Serializable{
        private static final long serialVersionUID = -2764017481108945198L;
        private final E[] a;

        ArrayList(E[] array) {
            //requireNonNull只是判断参数array是否为空,空抛出异常
            a = Objects.requireNonNull(array);
        }

        @Override
        public int size() {
            return a.length;
        }

        @Override
        public E get(int index) {
            return a[index];
        }
//重写了set方法,所以对list是可以进行set操作的。当然如果index超出了原来数组的大小,还是会报ArrayIndexOutOfBoundsException异常的
        @Override
        public E set(int index, E element) {
            E oldValue = a[index];
            a[index] = element;
            return oldValue;
        }

    ...
}

注意到asList返回的是一个静态内部类示例,且内部类中存储数据的是一个final类型的数组。从这里我们也知道,final类型的数组有些特殊,并不是说完全不可改变,只是数组的大小不能变,数组的元素却还可以替换。
另一方面,静态类并没有重写add,remove方法。而它的父类AbstractList中对于add,remove方法是怎么定义的呢

public boolean add(E e) {
        add(size(), e);
        return true;
    }
public void add(int index, E element) {
        throw new UnsupportedOperationException();
    }

 public E remove(int index) {
        throw new UnsupportedOperationException();
    }

这也就是为什么在对Arrays.asList()返回的列表进行增添和删除操作会抛出UnsupportedOperationException异常的原因了。

这里我们可以补充一下final的知识。当对基本数据类型运用final时,数据即被锁定,无法修改。但对自定义类型,类等引用类型运用final时,final
将引用固定。一旦引用被初始化指向某个对象,那么这个引用就不能再指向别的对象了,但对象自身确是可以改变的。数组也是一种对象。
如果我们在给final变量初始化一个对象前,将对象赋给另一个引用a,那么就可以在外部通过a来改变这个对象。而final保持恒定不变的只是自身的引用,对象本身却还是改变了。如下例:

public class Main {
    private final String[] arr;
    public Main(String[] arr){
        this.arr = arr;
    }

    public static void main(String[] args) {
        String[] a = new String[]{"123","234","345"};
        Main main = new Main(a);
        a[0] = "000";
        main.arr[1] = "123";
        for (String s : main.arr) {
            System.out.print(s+" ");
        }
    }
}

在给final变量arr初始化 new String[]{“123”,”234”,”345”};对象的时候,我把对象先赋给了引用a,初始化arr之后,arr指向了 new String[]{“123”,”234”,”345”}这个对象,但a也指向这个对象。final保证了arr只能指向这个对象,无法另行指向别的数组。但保证不了对象自身的改变,我通过a改变了这个对象。
所以在用final的时候,最佳实践是只用在基本数据类型上。否则可能会出现不可预料的错误

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

Arrays.asList(T...a)的使用问题 的相关文章

  • 虚拟服务器和vdi,VDI虚拟化平台搭建 01--VDI基本环境准备

    说明 此文章仅用于学习研究 不做任何商业用途 VDI 虚拟桌面基础架构 Virtual Desktop Infrastructure VDI基本软件硬件版本 服务器系统版本 exsi 6 7 vcenter版本 6 7 Vmware Hor
  • Typescript 基础类型 —— 布尔值 Boolean

    在JavaScript和TypeScript里布尔值都叫做boolean 表示逻辑值 true 和 false 关键字 boolean 实例 let isRes boolean false 编译结果 var isRes false 试图给
  • 【读懂Autosar代码】-1-概述

    点击返回 Autosar从入门到精通 实战篇 总目录 案例背景 共5页精讲 聊一聊这些封装中关键字宏的命名是如何构成的 FUNC FUNC P2CONST FUNC P2VAR P2VAR P2CONST CONSTP2VAR CONSTP
  • 论文期刊一般的审稿流程

    一 经常在网上看到某某人在问什么期刊的审稿周期 或者是投稿已多久怎么还没消息之类的帖子 作为经常帮国内外期刊审稿的人 对编辑部相对有所了解 因此特意发帖告知 供大家交流 论文审稿是个复杂的过程 并不是像大部分作者想象的那样送个一个专家看个几
  • String 判断字符串是否包含某个字符

    contains 判断 s 是否包含 ss 包含返回true 不包含返回false String s 你好 String ss 你 boolean ii s contains ss if ii true System out println
  • STM32调试特定函数出现Cannot access Memory

    MDK5出现Cannot access Memory 1 问题 2 原因 3 总结 1 问题 程序每次执行到了特定函数的位置时 keil里面全速运行 一直出现Cannot access Memory 再后面就是进入硬件错误中断了 执行到这个
  • C#使用COM+实现事务控制,操作多个数据库

    其中大部分内容参考自http blog itpub net 10752043 viewspace 991224 上面的是sqlserver的操作方式 因为我实际项目是用的oracle 就拿oracle试了一下 为了自己记录或者方便其他人 其
  • Linux下如何配置环境变量

    基础知识 首先 我们来了解一下什么是 环境变量 环境变量 通俗讲是操作系统或程序执行时候默认设定的参数 比如 PATH 路径变量 当要执行某个命令或程序的时候默认寻找的路径 然后 我们再来了解一下环境变量都有哪些类型 环境变量的分类 根据变
  • C++的类型

    C 的类型 按照标准 C 只有两种类型 基本类型和复合类型 但是里面细节多导致彻底理解它们有难度 所以这里只是简单总结一下 基本类型 基本类型分成算术类型和两种特殊的类型 算术类型 算术类型分成整数类型和浮点数类型两种 整数类型 以下都是整
  • 在springboot中使用Sse(Server-sent Events)Web实时通信技术-服务器发送事件SseEmitter

    最近在练习项目时需要用到消息实时推送技术 了解到有两种实时通信技术供我选择 SSE和WebSocket 详细了解后得知SSE是基于http协议 无需导入其他依赖 特点是服务端主动给客户端推送消息 单向 适合浏览器端只做数据接收 而webso
  • 华为OD机试真题-路灯照明问题-2023年OD统一考试(B卷)

    题目描述 在一条笔直的公路上安装了N个路灯 从位置0开始安装 路灯之间间距固定为100米 每个路灯都有自己的照明半径 请计算第一个路灯和最后一个路灯之间 无法照明的区间的长度和 输入描述 第一行为一个数N 表示路灯个数 1 lt N lt
  • Pysot训练自己的数据集

    数据集预处理操作 Pysot训练自己数据集前的预处理 Vesper0412的博客 CSDN博客 Pysot源码地址 https github com STVIR pysot 1 linux系统激活环境 conda activate pyto
  • 机器学习课程学习阶段总结

    机器学习课程学习阶段总结 线性回归 逻辑回归 逻辑回归 是一种分类算法 和之前的线性回归不是同一类问题 但是对于处理问题上有相同的思想 对于线性回归问题 有较容易理解的思路 首先指定一个形式确定的 h x Tx h theta x thet
  • 笔记本连接RK61键机械键盘非损坏的win和alt对调,数字键失灵以及特殊字母键失灵恢复

    1 问题描述 在打游戏或者码字的时候 无意中按下了键盘模式切换按键 导致了键盘的假性失灵状态 具体表现为 1 win和alt键功能对调 win按键无反应 alt键出现windows窗口 虽然不影响使用 但是很别扭 2 数字键失灵 键盘打不出

随机推荐

  • 网络安全有哪些经典笑话

    今天程序员同事发了一个链接给我 点开是一个调侃程序员有哪些经典笑话的帖子 给我看乐了 诸如 老婆给当程序员的老公打电话 下班顺路买一斤包子带回来 如果看到卖西瓜的 就买一个 当晚 程序员老公手捧一个包子进了家门 老婆怒道 你怎么就买了一个包
  • Android BLE 快速开发示例

    目录 概述 1 FastBle的使用 2 BLE开发实践方面的理解 3 FastBle源码解析 概述 思来想去 还是写这篇博文 记录一下 当时学习BLE的一些心得 重捡回当前Android知识 想深入了解蓝牙通讯知识 这个案例是非常不错的选
  • 毕业设计 - 基于单片机的测谎仪

    文章目录 1 简介 2 实现原理 3 主要器件 4 实现效果 正常情况 未说谎 异常情况 说谎了 5 部分实现代码 6 最后 1 简介 Hi 大家好 学长今天向大家介绍一个有趣的单片项目 基于单片机的测谎仪 大家可用于 课程设计 或 毕业设
  • 大数据技术(林子雨版)——期末复习知识点

    gt 大数据 云计算 大数据时代的三次信息化浪潮 时间 标志 解决的问题 代表企业 1980年前后 个人计算机 信息处理 Intel IBM 1995年前后 互联网 信息传输 谷歌 腾讯 2010年前后 大数据 云计算 物联网 信息爆炸 亚
  • Windows “Win+R“命令行运行常用命令

    Windows Win R 命令行运行常用命令 Windows操作系统提供了许多方便的方式来执行各种任务 其中之一是使用 Win R 运行命令行 这个快捷键组合可以让您迅速启动各种应用程序 工具和系统实用程序 而无需通过开始菜单或桌面快捷方
  • 【仲裁器】轮询仲裁round-robin,rr

    起因 在多主单从的设计中 当多个源端同时发起传输请求时 需要仲裁器根据优先级来判断响应哪一个源端 轮询仲裁 各个源端优先级相同 当其同时发起请求时 依次进行响应 电路图 代码 module rr arb input clk input rs
  • 区块链(二)-私有链的搭建

    私有链 搭建私有链 首先需要写一个创世块文件 创世块就是我自己链上的第一个区块 config nonce 0x0000000000000042 mixhash 0x00000000000000000000000000000000000000
  • 简单介绍Hyperledger fabric是什么

    Hyperledger Fabric作为超级账本的项目之一 目前基于它开发的区块链项目非常多 Linux基金会于2015年成立超级账本 以推进跨行业的区块链技术 相对于申报一个区块链标准 它鼓励通过社区合作的方式来发展区块链技术 带着知识产
  • 论git中使用https和ssh协议的区别

    论git中使用https和ssh协议的区别 SHELDON CUI S BLOG 2017 09 08 git https ssh 心得 http好还是ssh好 git可以使用四种主要的协议来传输资料 本地协议 Local HTTP 协议
  • TightVNC H264编解码(一)

    时光流逝 时间过的真快啊 疲于工作 发现近一个多月没写文章了 此文算是对最近的工作做个总结吧 经过尽二个月的不断摸索 TightVNC终于支持H264编解码了 前期真正编写H264编解码器只花了一周左右时间 但是测试发现效果并不是太理想 帧
  • 2022年android面试题,Android资深架构师分享学习经验及总结

    前言 最近有些朋友提问 Android QQ空间 换肤实现原理是什么 于是 我决定在这里做一下回答 对这个方面感兴趣的朋友也可以来看下 手q的换肤机制主要是通过拦截系统resource中的sPreloadedDrawables静态缓存变量
  • 为什么说“低估值买入,买到即赚到”?

    投资究竟能不能挣到钱 到底是由哪个环节决定的 买入还是卖出 直觉上说 这个问题的答案理所当然是 卖出 就连路边卖杂货的小商贩都明白 只要卖出价高于买入价 就可以挣到钱 直到我看了 穷查理宝典 接触到价值投资的理念 想法有了根本性改变 买入的
  • 对opencl helloworld代码的修正

    由于代码比较乱 数组也容易越界 故重新加了个类 用了stl vector 代码如下 test cl kernel void hello kernel global const float a global const float b glo
  • java jdbc线程池的使用

    好久没直接使用jdbc了 今天重温了一下相关知识 并对连接池的使用写了简单的示例 记录在此以便需要的同行参考和方便自己查阅 不足之处欢迎批评指正 1 dbcp数据源 所需jar包 dbcp 连接池的实现 commons pool2 连接池实
  • RedisTemplate 使用 Redis 缓存

    与使用注解方式不同 注解方式可以零配置 只需引入依赖并在启动类上加上 EnableCaching 注解就可以使用 而使用 RedisTemplate 方式麻烦些 需要做一些配置 Redis 配置 第一步还是引入依赖和在启动类上加上 Enab
  • 设计模式:策略模式

    我们玩游戏会有策略游戏 设计模式也会有策略模式 最开始接触策略模式的使用场景 是关于校验 针对不同的业务要进行不同的校验 同样的场景 优惠券折扣 不同渠道的信息发布等 Strategy Design Pattern 以下是GoF 是指提出和
  • 开发实况4.1.linux相关-CRT连接虚拟机提示用户名或密码错误

    文章目录 开发实况4 1 linux相关 CRT连接虚拟机提示用户名或密码错误 一 简介 二 问题解决 开发实况4 1 linux相关 CRT连接虚拟机提示用户名或密码错误 一 简介 已知我输入的用户名和密码正确但是却跳failed 二 问
  • Mac下使用GitHub+Hexo搭建个人博客

    首发链接 开始之前需要在电脑上安装好Git和node js Mac上可以使用Homebrew命令行工具来安装Git和node js 安装Homebrew 在命令行工具输入以下命令 如果已经安装过Homebrew可以忽略 usr bin ru
  • pjsip库使用时,顺序也有一定要求,

    LIBS PWD third lib pjsip lib libpjsua aarch64 unknown linux gnu a LIBS PWD third lib pjsip lib libpjsip ua aarch64 unkno
  • Arrays.asList(T...a)的使用问题

    我们经常会使用Arrays asList来初始化一个列表List 例如 List