Java数组转集合与集合转数组的坑
在Java中将数组转为集合,会用到Arrays.asList()的方法,然而,这个方法却与我们的预期期望存在一些出入,当用到asList方法将数组转化成List列表时,对得到的List列表进行add()和remove()操作, JVM会抛出异常:java.lang.UnsupportedOperationException异常
Arrays.asList返回的是同样的ArrayList,为什么就不能使用add和remove方法呢?
接下来我们来看一下Arrays.asList 源码
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
/**
* @serial include
*/
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) {
a = Objects.requireNonNull(array);
} @Override
public int size() {
return a.length;
} @Override
public Object[] toArray() {
return a.clone();
} @Override
@SuppressWarnings("unchecked")
AbstractList源码:
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
/**
* Sole constructor. (For invocation by subclass constructors, typically
* implicit.)
*/
protected AbstractList() {
}
/**
* Appends the specified element to the end of this list (optional
* operation).
*
* <p>Lists that support this operation may place limitations on what
* elements may be added to this list. In particular, some
* lists will refuse to add null elements, and others will impose
* restrictions on the type of elements that may be added. List
* classes should clearly specify in their documentation any restrictions
* on what elements may be added.
*
* <p>This implementation calls {@code add(size(), e)}.
*
* <p>Note that this implementation throws an
* {@code UnsupportedOperationException} unless
* {@link #add(int, Object) add(int, E)} is overridden.
*
* @param e element to be appended to this list
* @return {@code true} (as specified by {@link Collection#add})
* @throws UnsupportedOperationException if the {@code add} operation
* is not supported by this list
* @throws ClassCastException if the class of the specified element
* prevents it from being added to this list
* @throws NullPointerException if the specified element is null and this
* list does not permit null elements
* @throws IllegalArgumentException if some property of this element
* prevents it from being added to this list
*/
public boolean add(E e) {
add(size(), e);
return true;
}
/**
* {@inheritDoc}
*
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
abstract public E get(int index);
/**
* {@inheritDoc}
*
* <p>This implementation always throws an
* {@code UnsupportedOperationException}.
*
* @throws UnsupportedOperationException {@inheritDoc}
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
* @throws IllegalArgumentException {@inheritDoc}
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E set(int index, E element) {
throw new UnsupportedOperationException();
}
/**
* {@inheritDoc}
*
* <p>This implementation always throws an
* {@code UnsupportedOperationException}.
*
* @throws UnsupportedOperationException {@inheritDoc}
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
* @throws IllegalArgumentException {@inheritDoc}
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
/**
* {@inheritDoc}
*
* <p>This implementation always throws an
* {@code UnsupportedOperationException}.
*
* @throws UnsupportedOperationException {@inheritDoc}
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E remove(int index) {
throw new UnsupportedOperationException();
}
由源码可见,UnsupportedOperationException 是AbstractList抛出的,因为Arrays中的ArrayList并没有实现remove()和add()方法,所以抛出了异常。
所以说 Arrays.asList 返回的 List 是一个不可变长度的列表,此列表不再具备原 List 的很多特性,因此慎用 Arrays.asList 方法。
ArrayList中构造方法:
ArrayList(E[] array) {
a = Objects.requireNonNull(array);
}
看一段这样的代码:
import java.util.Arrays;
import java.util.List; public class Test2{
public static void main(String[] args) {
int[] array = new int[]{1,2,3,4,5};
List list = Arrays.asList(array);
System.out.println(list.size());
}
}
Arrays 的内部类 ArrayList 构造方法接收的是一个泛型数组,即数组类型不能为基本类型,应该为其对应的包装类型(传即入引用类型),否则传入的基本类型的整个数组,将被编译器视为一个引用参数,
所以原始类型不能作为 Arrays.asList 方法的参数,否则会被当做一个参数
再来看看在Java中将集合转为数组,ArrayList提供了一个将List转为数组的一个非常方便的方法toArray。toArray有两个重载的方法:
@Override
public Object[] toArray() {
return a.clone();
}
@Override
@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {
int size = size();
if (a.length < size)
return Arrays.copyOf(this.a, size,
(Class<? extends T[]>) a.getClass());
System.arraycopy(this.a, 0, a, 0, size);
if (a.length > size)
a[size] = null;
return a;
}
对于第一个重载方法,是将list直接转为Object[] 数组;
第二种方法是将list转化为你所需要类型的数组,当然我们用的时候会转化为与list内容相同的类型。
若采用第一种toArray方法,是这样写:
ArrayList<String> list=new ArrayList<String>();
for (int i = 0; i < 10; i++) {
list.add(""+i);
} String[] array= (String[]) list.toArray();
结果一运行,报错:
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
第一个方法不能将Object[] 转化为String[],我们需要修改为:
Object[] arr = list.toArray();
for (int i = 0; i < arr.length; i++) {
String e = (String) arr[i];
System.out.println(e);
}
建议用第二种方法:普通数组基本类型必须改为包装类
import java.util.ArrayList;
import java.util.List; public class Test2{
public static void main(String[] args) {
List<Integer> list = new ArrayList();
list.add(1);
list.add(2);
list.add(3);
Integer[] array = new Integer[list.size()];
list.toArray(array);
for (int i:array){
System.out.print(i+" ");
}
}
}
或者
set.toArray(new Integer[set.size()]);
set好处是去除重复元素
Java数组转集合与集合转数组的坑的更多相关文章
- 黑马程序员——JAVA基础之Collections和Arrays,数组集合的转换
------- android培训.java培训.期待与您交流! ---------- 集合框架的工具类: Collections : 集合框架的工具类.里面定义的都是静态方法. Col ...
- Java基础知识强化之集合框架笔记01:集合的由来与数组的区别
1. 集合的由来: 我们学习的是面向对象语言,而面向对象语言对事物的描述是通过对象体现的,为了方便对多个对象进行操作,我们就必须把这多个对象进行存储.而要想存储多个对象,就不能是一个基本的变量,而应该 ...
- Java学习:集合的使用与数组的区别
ArrayList 集合 ArrayList 集合 ArrayList<String> list = new ArrayList<>(); 对于ArrayList来说,有一个尖 ...
- Java中定义不了可变长数组怎么办---集合 泛型
一.集合(Collections) Java使用集合来组织和管理对象. 1.Java的集合类 集合类主要负责保存.盛装和管理对象,因此集合类也被称为容器类. 集合类分为Set.List.Map和Que ...
- java基础(10)---leetcode的String、数组以及集合的一些使用
整数 一.整数反转_7 /* 12345 变成 54321 */ public class 整数反转_7 { public static void main(String[] args){ int x ...
- java基础(4)---引用数据类型(数组、字符串、集合)
一.数组 格式: int[] nums; 1. 数据类型[] 数组名称; 2. 数据类型 数组名称[]; (不太推荐) 动态初始化: new int[4] 数据类型[] 数组名称 = new 数据类 ...
- Java ArrayList和Vector、LinkedList与ArrayList、数组(Array)和列表集合(ArrayList)的区别
ArrayList和Vector的区别ArrayList与Vector主要从二方面来说. 一.同步性: Vector是线程安全的,也就是说是同步的,而ArrayList是线程序不安全的,不是同步 ...
- JSon_零基础_008_将JSon格式的"数组"字符串转换为List集合
将JSon格式的"数组"字符串转换为List集合. 应用此技术从一个json对象字符串格式中得到一个java对应的对象. JSONObject是一个“name.values”集合, ...
- 数组Array和列表集合ArrayList、LinkedList和Vector的区别
一.ArrayList和Vector的区别 ArrayList与Vector主要从以下方面来说. 1.同步性: Vector是线程安全的,也就是说是同步的,而ArrayList是线程序不安全的,不是同 ...
- 数组转集合、集合转数组、字符串数组与int型、long型数组等的转换
在项目中经常会遇到数组转集合.集合转数组.数组之间类型转换等操作 1.数组转集合 为了实现把一个数组转换成一个ArrayList,很多Java程序员会使用如下的代码: String str[] = { ...
随机推荐
- Ingress-Nginx
注意: 本文只用的ingress-nginx版本为0.24.1,可在官方网站自行下载 https://github.com/kubernetes/ingress-nginx 一.Ingress-Ng ...
- ROS学习笔记(二) :使用roslaunch
目录 roslaunch roslaunch的使用 以turtlesim为例 roslaunch roslaunch是ros自带的一个库,使用roslaunch可以同时运行多个节点,通过编写launc ...
- 腾讯面试Android高级岗,居然被一个多线程基础面倒了?
前言 一个在深圳从事开发五年的老友一个月前从原公司辞职后,昨天去腾讯总部面试Android高级岗,一面的时候,自我介绍后,陆陆续续问了很多问题,有着五年的从业经验很多项目开发的技术问题都回答的很通顺, ...
- Linux 安装Docker compose 快速方法
https://blog.csdn.net/ysk_xh_521/article/details/80443509 安装pipyum -y install epel-releaseyum -y ins ...
- 异常CLRDBG_NOTIFICATION_EXCEPTION_CODE( 0x04242420)的抛出过程
新建一个c#控制工程,就用自动生成的代码,不用补任何代码,如下: using System; using System.Collections.Generic; using System.Linq; ...
- 图像处理pillow模块
pillow模块: -->基本的图像处理模块 Pip install pillow from PIL import Image #1.读取图片 im = Image.open('/test.jp ...
- django_settings源码解析
目录 配置文件插拔式设计: 简单版: 复杂版 importlib 与`__import__的区别: 配置文件插拔式设计: 项目配置文件插拔式设计: 基于django settings源码实现自己项目配 ...
- [300iq Contest 1-D]Dates
传送门 Description 每个妹子匹配一个时间区间,每个时间最多选择\(a_i\)个妹子,每个妹子有一个快乐值,最大化总快乐值 Solution 贪心,从大往小取,能取则取 判断是否可以有完美匹 ...
- dockerfile+docker-compose
Dockerfile 一.简介 1.1 dockerfile中常用的命令合集 1.2 docker build 基于dockerfile制作镜像的命令 docker build [OPTIONS] P ...
- vue+element table的弹窗组件
在处理表格编辑相关的需求,是需要做一个弹框进行保存的:或者查看表格数据的详细信息时,也是需要做弹窗: 当然 ,这是类似于这样的 ,当然 element 已经帮我们做好 弹窗这一块 主要 我想记录的是 ...