从arrays.aslist到collection.toarray()(代码片段)

唐僧洗澡不秃头 唐僧洗澡不秃头     2022-12-27     278

关键词:

Arrays.asList()

简介

Arrays.asList()在平时开发中还是比较常见的,我们可以使用它将一个数组转换为一个List集合。

String[] myArray = "Apple", "Banana", "Orange";
List<String> myList = Arrays.asList(myArray);
//上面两个语句等价于下面一条语句
List<String> myList = Arrays.asList("Apple","Banana", "Orange");

源码对于这个方法的说明:

/**
  *返回由指定数组支持的固定大小的列表。此方法作为基于数组和基于集合的API之间的桥梁,
  * 与 Collection.toArray()结合使用。返回的List是可序列化并实现RandomAccess接口。
  */
public static <T> List<T> asList(T... a) 
    return new ArrayList<>(a);

《阿里巴巴Java 开发手册》对其的描述

Arrays.asList()将数组转换为集合后,底层其实还是数组,《阿里巴巴Java 开发手册》对于这个方法有如下描述:
也就是Arrays转成List,是转成Arrays的内部类ArrayList,它继承了AbstractList,但是没有对add/remove/clear方法进行重写,所以调用这些方法是会直接抛出UnsupportedOperationException异常

阿里巴巴Java开发手-Arrays.asList()方法

传递的数组必须是对象数组,而不是基本类型。Arrays.asList()是泛型方法,传入的对象必须是对象数组。

int[] myArray = 1, 2, 3;
List myList = Arrays.asList(myArray);
System.out.println(myList.size());//1
System.out.println(myList.get(0));//数组地址值
System.out.println(myList.get(1));//报错:ArrayIndexOutOfBoundsException
int[] array = (int[]) myList.get(0);
System.out.println(array[0]);//1

当传入一个原生数据类型数组时,Arrays.asList() 的真正得到的参数就不是数组中的元素,而是数组对象本身!此时List 的唯一元素就是这个数组,这也就解释了上面的代码。

我们使用包装类型数组就可以解决这个问题。

Integer[] myArray = 1, 2, 3;

但是,使用集合的修改方法:add()、remove()、clear()会抛出异常。

List myList = Arrays.asList(1, 2, 3);
myList.add(4);//运行时报错:UnsupportedOperationException
myList.remove(1);//运行时报错:UnsupportedOperationException
myList.clear();//运行时报错:UnsupportedOperationException

Arrays.asList() 方法返回的并不是 java.util.ArrayList ,而是 java.util.Arrays 的一个内部类,这个内部类并没有实现集合的修改方法或者说并没有重写这些方法。

List myList = Arrays.asList(1, 2, 3);
System.out.println(myList.getClass());//class java.util.Arrays$ArrayList

看一下java.util.AbstractList的remove()方法,这样我们就明白为啥会抛出UnsupportedOperationException。

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

如何正确的将数组转换为ArrayList?

stackoverflow:https://dwz.cn/vcBkTiTW

  1. 自己动手实现(教育目的)
static <T> List<T> arrayToList(final T[] array) 
  final List<T> l = new ArrayList<T>(array.length);

  for (final T s : array) 
    l.add(s);
  
  return l;


Integer [] myArray =  1, 2, 3 ;
System.out.println(arrayToList(myArray).getClass());//class java.util.ArrayList
  1. 最简便的方法(推荐)
List list = new ArrayList<>(Arrays.asList("a", "b", "c"))
  1. 使用 Java8 的Stream(推荐)
Integer [] myArray =  1, 2, 3 ;
List myList = Arrays.stream(myArray).collect(Collectors.toList());
//基本类型也可以实现转换(依赖boxed的装箱操作)
int [] myArray2 =  1, 2, 3 ;
List myList = Arrays.stream(myArray2).boxed().collect(Collectors.toList());

Collection.toArray()方法使用的坑&如何反转数组

该方法是一个泛型方法: T[] toArray(T[] a); 如果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/

不要在 foreach 循环里进行元素的 remove/add 操作

如果要进行remove操作,可以调用迭代器的 remove 方法而不是集合类的 remove 方法。因为如果列表在任何时间从结构上修改创建迭代器之后,以任何方式除非通过迭代器自身remove/add方法,迭代器都将抛出一个ConcurrentModificationException,这就是单线程状态下产生的 fail-fast 机制。
关于fail-fast和fail-safe

2.fail-safe 在遍历的时候只是拷贝一份副本,在副本上进行遍历,允许在遍历的过程中对容器中的数据进行修改,所以这种机制会使你此次读到的数据不一定是最新的数据。
3.在fail-safe集合中不能存储 null 值,因为你无法判断对应的 key 是不存在还是为空,因为你无法再调用一次contain(key)来对 key 是否存在进行判断.
fail-fast 机制 :fail-fast集合中,会维护一个modCount,每次修改是会加1,而在遍历时会判断modCount是否等于exceptionModCount,如果不相等,会抛出ConcurrentModificationException

Java8开始,可以使用Collection#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.util包下面的所有的集合类都是fail-fast的,而java.util.concurrent包下面的所有的类都是fail-safe的。

从arrays.aslist到collection.toarray()(代码片段)

...此方法作为基于数组和基于集合的API之间的桥梁,*与Collection.toArray()结合使用。返回的List是可序列化并实现RandomAccess接口。*/publicstatic<T>List<T>asList(T...a)returnnewArrayList<>(a);《阿里巴巴Java开发手册》对其的描述Arra... 查看详情

持有对象---arrays.aslist()和collections.addall()的性能比较

...portjava.util.ArrayList; importjava.util.Arrays; importjava.util.Collections; importjava.util.List; publicclassArraysCompareCollectionsTest publicstaticvoidmain(String[]args) intcount=10000000;//通过改变循环次数来放大或放小结果 System.out.println("A... 查看详情

arrays.aslist()vscollections.singletonlist()(代码片段)

Collections.singletonList(something)是不可变的,对Collections.singletonList(something)返回的列表所做的任何更改将导致UnsupportedOperationException 。Arrays.asList(something)允许Arrays.asList(something) 更改 。  查看详情

数组的 Arrays.asList()

】数组的Arrays.asList()【英文标题】:Arrays.asList()ofanarray【发布时间】:2010-11-1722:31:39【问题描述】:这个转换有什么问题?publicintgetTheNumber(int[]factors)ArrayList<Integer>f=newArrayList(Arrays.asList(factors));Collections.sort(f);returnf.ge 查看详情

持有对象(集合)

添加一组元素在java.util包中的Arrays和Collections类中都有很多实用方法,可以在一个Collection中添加一组元素。Arrays.asList()方法接受一个数组或是一个用逗号分隔的元素列表(使用可变参数),并将其转换为一个List集... 查看详情

java集合--疑难点总结(arrays.aslist()正确使用collection.toarray()正确使用反转数组foreach循环不要进行元素的remove/add操作)(代码片段)

...#xff08;推荐)1.4.5list自带的addAll方法1.4.6使用ApacheCommonsCollections2.Collection.toArray()正确使用、反转数组3.不要在foreach循环里进行元素的remove/add操作3.1正确示例3.2错误示例1.Arrays.asList()正确使用1.1简介Arrays.asList()在平时开发中还是... 查看详情

collection的实现——学生选课

通过addAll方法往list对象添加课程:Course[]course={newCourse("3","离散数学"),newCourse("4","汇编语言")};coursesToselect.addAll(Arrays.asList(course));/**通过Arrays.asList将数组course转换成List传递进coursesToselect*此时3,4课程分别在List的2,3 查看详情

arrays.aslist中所遇到的坑

...supportedOperationException异常从代码定位来看,原来是使用了Arrays.asList()方法时把一个数组转化成List列表时,对得到的List列表进行add()和remove()操作,所以导致了这个问题。 对于这个问题,现在来总结下,当然会总结Arrays下面的... 查看详情

关于不可变列表(由 Arrays.asList() 创建)

】关于不可变列表(由Arrays.asList()创建)【英文标题】:RegardingimmutableList(createdbyArrays.asList())【发布时间】:2014-10-1608:04:28【问题描述】:当我们使用java.util.Arrays.asList()从数组创建列表时,列表是不可变的。我只是想知道当List... 查看详情

arrays.aslist()返回一个特殊的“arraylist”

一个Arrays.asList()基本的用法:String[]str=newString[]{"1","2","3"};ArrayListal=newArrayList(Arrays.asList(str));//将数组元素添加到集合的一种快捷方式有时候这样使用就有可能出现问题:String[]str=newString[]{"1","2","3"};Listaslist=Arrays.asLis 查看详情

可变参数的使用(代码片段)

...rrays.asList(true);Listlist2=Arrays.asList(5);Listlist3=Arrays.asList("a");Collectionc=newArrayList();c.add("a");c.add(4);List、Collection都是泛型类,所以不带尖括号参数时,Arrays.asList()、c.add()都是泛型方法,所以其()内都可以些任何类型数据;  &nb... 查看详情

arrays.aslist(代码片段)

Leetcode111二叉树最小深度给定一颗二叉树,求根节点到叶子节点的最短路径(最小深度)classSolutionpublicintminDepth(TreeNoderoot)//若无根节点(空树),则返回0if(root==null)return0;//叶子节点,向上返回1,递归结束elseif(root!=null&&root.left==n... 查看详情

Arrays.asList() 不能正常工作?

】Arrays.asList()不能正常工作?【英文标题】:Arrays.asList()notworkingasitshould?【发布时间】:2010-11-3020:59:24【问题描述】:我有一个float[],我想获得一个包含相同元素的列表。我可以做一件丑陋的事情,将它们一一添加,但我想使... 查看详情

streamideainspectionwarning(代码片段)

...esimplified.Itallowstoavoidcreatingredundanttemporaryobjectswhentraversingacollection.Thefollowingcallchainsarereplacedbythisinspection:collection.stream().forEach()→collection.forEach()collection.stream().collect(toList/toSet/toCollection())→newCollectionType<>(collection)collection... 查看详情

arrays.aslist使用误区(代码片段)

       Arrays.asList使用的jar包是importjava.util.Arrays;  Arrays.asList是使用该jar中的ArrayList方法 1、 基本类型数组Int[]intArr=1,2,3;ListlistArr=Arrays.asList(int 查看详情

arrays.aslist的用法

使用工具类Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方法,它的add/remove/clear方法会抛出UnsupportOperationException异常说明:asList的返回对象是一个Arrays内部类,并没有实现集合的修改方法。Arrays.asList体现的是适配... 查看详情

Arrays.asList(array) 和 new ArrayList<Integer>(Arrays.asList(array)) 的区别

】Arrays.asList(array)和newArrayList<Integer>(Arrays.asList(array))的区别【英文标题】:DifferencebetweenArrays.asList(array)andnewArrayList<Integer>(Arrays.asList(array))【发布时间】:2013-05-2019:49:21【问题描述】:有什么区别List&lt;I 查看详情

Arrays.asList(int [])不工作[重复]

】Arrays.asList(int[])不工作[重复]【英文标题】:Arrays.asList(int[])notworking[duplicate]【发布时间】:2015-10-0323:58:55【问题描述】:当我运行以下代码时,没有输出任何输出。int[]array=3,2,5,4;if(Arrays.asList(array).contains(3))System.out.println("Th... 查看详情