Java数组转集合与集合转数组的坑
Java数组转集合与集合转数组的坑
在Java中将数组转为集合,会用到Arrays.asList()的方法,然而,这个方法却与我们的预期期望存在一些出入,当用到asList方法将数组转化成List列表时,对得到的List列表进行add()和remove()操作, JVM会抛出异常:java.lang.UnsupportedOperationException异常
Arrays.asList返回的是同样的ArrayList,为什么就不能使用add和remove方法呢?
接下来我们来看一下Arrays.asList 源码
public static List 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 extends AbstractCollection implements List {
/** * 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方法,是这样写:
复制代码
1 ArrayList list=new ArrayList();
2 for (int i = 0; i < 10; i++) {
3 list.add(""+i);
4 }
5
6 String[] array= (String[]) list.toArray();
复制代码
结果一运行,报错:
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
第一个方法不能将Object[] 转化为String[],我们需要修改为:
1 Object[] arr = list.toArray();
2 for (int i = 0; i < arr.length; i++) {
3 String e = (String) arr[i];
4 System.out.println(e);
5 }
建议用第二种方法:
复制代码
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好处是去除重复元素
原文地址https://www.cnblogs.com/hetaoyuan/archive/2019/07/24/11236999.html

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
SQL 十位随机数(大小写字母+数据)
SQL 十位随机数(大小写字母+数据)USE [TEST]GO/ Object: UserDefinedFunction [dbo].[RANDTENNUMS] Script Date: 2019/7/23 15:40:16 **/SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE function [dbo].[RANDTENNUMS]()returns varchar(10)asbeginDECLARE @i int DECLARE @flag intDECLARE @SerialNumber nvarchar(20)DECLARE @RANDS Numeric(38,38)--初始化设定SET @i=1SET @SerialNumber = ''--生成10位随机码WHILE @i<11BEGIN--设置随机,这个随机会选择字母(大小写)还是数字SELECT @RANDS = RAND_A FROM [dbo].[VW_RAND]SET @flag=ceiling(@RANDS *3) IF @flag=1 BEGIN--...
- 下一篇
解决python中的Non-UTF-8 code starting with ‘\xbs4’ in file错误
解决python中的Non-UTF-8 code starting with ‘xbs4’ in file错误出现错误如下图: 主要原因为编辑python脚本使用的编辑器编码有问题。我使用的编辑器是notepad++,由于没有做Python语言编辑配置,默认使用的是ANSI编码(右下角位置有编码格式),如下: python3使用的是utf-8编码,如果脚本文件全是英文字符,ANSI编码是utf-8编码的子集,解析是没有问题的。但是脚本文件中如果含有中文字符,如注释等,就会出现错误。 解决办法:将编码格式改为utf-8编码。 方法:点击【编码】,将编码改为utf-8 可以看到,改变编码以后,中文字符都已经变成了乱码,将乱码修改为中文即可。 修改后运行正常: 原文地址https://www.cnblogs.com/xbook-ben/archive/2019/07/24/11236421.html
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Windows10,CentOS7,CentOS8安装Nodejs环境
- Red5直播服务器,属于Java语言的直播服务器
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- SpringBoot2整合Redis,开启缓存,提高访问速度
- CentOS7,8上快速安装Gitea,搭建Git服务器
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池