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[] = { ...
随机推荐
- Linux的DNS主从服务器部署
下面的部署是在Linux的DNS正向解析部署上进行修改的. 如果有什么问题或者错误,可以访问上篇帖子 下面开始有关DNS的服务部署.<DNS主从服务器> 环境描述: 192.168.196 ...
- SQL注入总结
sqlMap介绍:sqlmap是一个自动化的SQL注入工具,其主要功能是扫描,发现并利用给定的URL的SQL注入漏洞,目前支持的数据库是MySQL, Oracle, PostgreSQL, Micro ...
- 页面预加载loading动画,再载入内容
默认情况下如果网站请求速度慢,所以会有一段时间的空白页面等等,用户体验效果不好,见到很多的页面都有预加载的效果,加载之前先加载一个动画,后台进程继续加载页面内容,当页面内容加载完之后再退出动画显示内容 ...
- shell脚本如何判断文件大小
转自:https://blog.csdn.net/lovegengxin/article/details/80762329 1 .ls -lls -l $filename | awk '{print ...
- python 通过scapy获取网卡列表
python通过scapy 获取网卡列表如下: #coding:utf-8 from scapy.all import * #显示网卡信息 show_interfaces() 运行结果如下:
- Git创建与简单使用
一. 服务器端 创建空的仓库(以项目tm201为例) 1. git账户登录 2. 新建仓库目录 mkdir tm101.git && cd tm201.git 3. git初始化新的空 ...
- USACO Superprime Rib
洛谷 P1218 [USACO1.5]特殊的质数肋骨 Superprime Rib 洛谷传送门 JDOJ 1673: Superprime Rib JDOJ传送门 题目描述 农民约翰的母牛总是产生最好 ...
- Windbg Register(寄存器)窗口的使用
寄存器是位于在 CPU 的小易失性内存单位. 许多寄存器专用于特定用途,并可用于用户模式应用程序使用的其他寄存器. 基于 x86 和基于 x64 的处理器在有可用的寄存器的不同集合. 如何打开寄存器窗 ...
- springboot使用thymeleaf模板问题
返回 org.thymeleaf.exceptions.TemplateInputException: Error resolving template [/implementsfun/index] ...
- PYTHON读取EXCEL内容再转变成HTML添加到OUTLOOK中
需求 读取excel里的表格里的内容,然后打开本机的outlook.把excel里的内容添加到正文里,注意.这里是要添加到正文!正文!正文!而不是添加到附件里 设计思路 1.excel处理 打开exc ...