[Java 基础] 深入理解List的toArray()方法和toArray(T[] a)方法
深入理解List的toArray()方法和toArray(T[] a)方法
这两个方法都是将列表List中的元素转导出为数组,不同的是,toArray()方法导出的是Object类型数组,而toArray[T[] a]方法导出的是指定类型的数组。
下面是两个方法的申明及说明,摘自Java8的API文档。
toArray()方法
会返回List中所有元素构成的数组,并且数组类型是Object[]。还要注意一点就是,返回的数组是新生成的一个数组,
也就是说,多次运行toArray()方法会获得不同的数组对象(可以理解存储的数组对象内存地址不一样),但是这些数组对象中内容一样的。
也就是说,toArray()返回的数组是安全的,你可以对它进行任意的修改,其原因就是List不会去维持一个对该返回的数组的引用。
下面是对基本数据类型:Integer测试
public static void main(String[] args) {List<Integer> list = new ArrayList<>();list.add(1);list.add(2);Object[] objects1 = list.toArray();Object[] objects2 = list.toArray();//比较二个新数组System.out.println("objects1 == objects2 : "+(objects1 == objects2));//对object1 对象的数组进行修改 不会影响到其他 引用的数组objects1[1]=4;//输出修改后的 数组System.out.println("show objects1: "+ Arrays.toString(objects1));//输出引用的数组System.out.println("show objects2: "+ Arrays.toString(objects2));//输出原来的数组System.out.println("show list: "+list);
}输出结果:objects1 == objects2 : false
show objects1: [1, 4]
show objects2: [1, 2]
show list: [1, 2]
可以看出确实toArray()返回的是一个新的数组对象地址,并且多次执行toArray()方法获得的是不同的数组对象,并且对其中一个数组进行修改,不会影响到其他toArray()方法获得的数组,并且也不会影响到list本身原来存储的元素值。
当我们list 换为其他类型对象的时候,也不影响
private static class People{String name;public People(String name){this.name = name;}@Overridepublic String toString() {return "People{" +"name='" + name + '\'' +'}';}
}public static void main(String[] args) {List<People> list = new ArrayList<>();list.add(new People("小明"));list.add(new People("小王"));Object[] objects1 = list.toArray();Object[] objects2 = list.toArray();System.out.println("objects1 == objects2 : "+(objects1 == objects2));objects1[1]=new People("小花");System.out.println("show objects1: "+ Arrays.toString(objects1));System.out.println("show objects2: "+ Arrays.toString(objects2));System.out.println("show list: "+list);输出结果:objects1 == objects2 : false
show objects1: [People{name=‘小明’}, People{name=‘小花’}]
show objects2: [People{name=‘小明’}, People{name=‘小王’}]
show list: [People{name=‘小明’}, People{name=‘小王’}]}
可以看到依然是和上面的分析结果一样,toArray()返回的是一个新的数组对象,对于toArray()返回的一个数组元素进行修改,不会影响到其他toArray()返回的数组对象,也不会影响list本身。
上面我们是对元素的自定义对象 Object1 进行修改的 ,下面我们对 元素对象本身进行 修改,?
//People类和上一个例子中的一样,这里不再列出了。
public static void main(String[] args) {List<People> list = new ArrayList<>();list.add(new People("小明"));list.add(new People("小王"));Object[] objects1 = list.toArray();Object[] objects2 = list.toArray();System.out.println("objects1 == objects2 : "+(objects1 == objects2));((People)objects1[1]).name = "小花";System.out.println("show objects1: "+ Arrays.toString(objects1));System.out.println("show objects2: "+ Arrays.toString(objects2));System.out.println("show list: "+list);
}输出结果:objects1 == objects2 : false
show objects1: [People{name=‘小明’}, People{name=‘小花’}]
show objects2: [People{name=‘小明’}, People{name=‘小花’}]
show list: [People{name=‘小明’}, People{name=‘小花’}]
对元素对象本身就行修改,会导致toArray()返回的所有数组中的内容都发生改变,包括原始的list容器里面的元素类容。从这个例子可以得出,如果list.toArray()返回的数组中存放的是list原始对象的引用,只是创建了一个新的数组来装这些引用,并没有对list中原始对象进行拷贝或复制。
toArray底层
我们可以发现 在ArrayList中的实现是调用了Arrays工具类的copyOf()方法,这个方法的作用就是 拷贝数组.
该方法是根据集合中元素的类型,传入一个相同类型的零长度的数组。返回一个指定类型的数组。
因为方法的需要,方法就是这么定义的
T[] toArray(T[] a) 参数传入一个数组,输出和参数同类型的数组,该参数相当于告诉方法要转为什么类型,所以一般传入个0长度的数组就可以了,即代码中的new String[]{}或new String[0]
toArray(T[] a)底层
总结:
- List接口的toArray()方法就是直接调用Arrays.copyOf(elementData,
size),将list中的元素对象的引用装在一个新的生成数组中。 - List接口的toArray(T[] a)方法会返回指定类型(必须为list元素类型的父类或本身)的数组对象,如果a.length小于list元素个数就直接调用Arrays的copyOf()方法进行拷贝并且返回新数组对象,新数组中也是装的list元素对象的引用,否则先调用System.arraycopy()将list元素对象的引用装在a数组中,如果a数组还有剩余的空间,则在a[size]放置一个null,size就是list中元素的个数,这个null值可以使得toArray(T[] a)方法调用者可以判断null后面已经没有list元素了。
结合查看的 地址
1.ArrayList的toArray
ArrayList提供了一个将List转为数组的一个非常方便的方法toArray。toArray有两个重载的方法:
第二种方法是将list转化为你所需要类型的数组,当然我们用的时候会转化为与list内容相同的类型。
ArrayList<String> list=new ArrayList<String>();
for (int i = 0; i < 10; i++) {list.add(""+i);
}String[] array= (String[]) list.toArray();
Object[] arr = list.toArray();
for (int i = 0; i < arr.length; i++) {String e = (String) arr[i];System.out.println(e);
}
实际上,将list转化为array的时候,第二种重构方法更方便,用法如下:
String[] array =new String[list.size()];
list.toArray(array);
//实际项目中
List<String> sList = new ArrayList<String>();
for (MergeSoft mergeSoft : list) {if(mergeSoft.getCollectSoft() != null){sList.add(mergeSoft.getCollectSoft().getSid());}
}
String[] sids = sList.toArray(new String[sList.size()]);
String[] devOnlyIds = collectSoftDao.queryDevOnlyIdBySid(sids);
public String[] queryDevOnlyIdBySid(String[] sid) {String paramsStr = ArrayUtils.joinStringForSql(sid, "'", ",");//数组数据转为:'B07D26B8A919082612F9EFA55A9AACFC','3EF11C53F437A33A47C0B363B8D661BC'String sql = "SELECT di.devOnlyId FROM cems_device_installsoft di WHERE sId IN ( "+paramsStr+" )";List<Object> object = getSession().createSQLQuery(sql).list();Set<String> set = new HashSet<String>();for (int i = 0; i < object.size(); i++) {set.add(object.get(i).toString());//object里有重复的数据,采用set去除重复的数据}String[] devOnlyIds = new String[set.size()]; //Set-->数组 set.toArray(devOnlyIds); return devOnlyIds;
}
总结:
3.总结
1、集合转数组用方法,比如:list.toArray(new String[list.size()]);
Set<String> set = new HashSet<String>();
for(int i=0; i < object.size(); i++){set.add(object.get(i).toString());
}
set.toArray(new String[set.size()]);
[Java 基础] 深入理解List的toArray()方法和toArray(T[] a)方法相关推荐
- 深入理解List的toArray()方法和toArray(T[] a)方法
深入理解List的toArray()方法和toArray(T[] a)方法 这两个方法都是将列表List中的元素转导出为数组,不同的是,toArray()方法导出的是Object类型数组,而toArr ...
- 详解List的toArray()方法和toArray(T[] a)方法
这两个方法都是将列表List中的元素转导出为数组,不同的是,toArray()方法导出的是Object类型数组,而toArray[T[] a]方法导出的是指定类型的数组. 下面是两个方法的申明及说明, ...
- List的toArray()方法和toArray(T[] a)方法
1.toArray()方法 会返回List中所有元素构成的数组,并且数组类型是Object[].还要注意一点就是,返回的数组是新生成的一个数组, 也就是说,多次运行toArray()方法会获得不同的数 ...
- jqgrid和ajax的区别,理解jqGrid的添加方法和Ajax请求
我有一个现有的项目,我需要维护,但是这是我第一次满足的jqGrid ...理解jqGrid的添加方法和Ajax请求 主要是,我有一个Product,即可以有多个Formule小号.每个Formule可 ...
- Node.js的环境搭建方法和 npm 的使用方法
Node.js的环境搭建方法和 npm 的使用方法 Node.js 环境的搭建 Node.js 介绍 Node.js 下载 配置Node.js node.js 测试 npm(包管理器)使用方法 npm ...
- 联想集群超算LICO初次使用踩坑说明(遇到的错误,一些使用方法和singularity新建容器方法)
联想集群超算LICO初次使用踩坑说明(遇到的错误,一些使用方法和singularity新建容器方法) 说明 本文主要写一些我这几天初次使用LICO的过程中遇到的一点问题和解决的办法,还有一些模块的规范 ...
- JavaSE学习之路:Idea小技巧一键生成标准JavaBean(一键生成构造方法和Setter和Getter方法)
Idea小技巧一键生成标准JavaBean(一键生成构造方法和Setter和Getter方法) 方法1:快捷键 快捷键:alt+insert或alt+fn+insert 1.生成有参和无参构造函数 p ...
- CString的Trim()方法和TrimStrat()和TrimEnd()方法,TrimRight()和TrimLeft() 方法
一. CString的Trim()方法和TrimStrat()和TrimEnd()方法.这三个方法用于删除字符串头尾出现的某些字符. Trim()删除字符串头部及尾部出现的空格,删除的过程为从外到内, ...
- Java基础——深入理解Java中的多线程(超级详细,值得你看)
Java中的多线程 进程(process)是程序的一次执行过程,或是正在运行的有一个程序,或是正在运行的一个程序.是一个动态的过程:有它自身的产生.存在和消亡的过程.--生命周期. 线程(thread ...
最新文章
- zabbix-proxy分布式监控配置
- 【linux基础】CMake如何生成动态链接库文件
- java8 多行字符串_Java8(2):Java8 对字符串连接的改进
- TortoiseGit上传项目到GitHub
- 阿里中台建设全解密:包含哪些内容?如何发挥作用?
- MyBatis-DynamicSQL IF判断
- 蒋涛:重新回归的我,将带领 CSDN 全方位升级,为 AI 转型者打造一站式平台
- LVS负载均衡中arp_ignore和arp_annonuce参数配置的含义
- 毕设题目:Matlab优化分配
- bin(二进制文件)
- 批量图片压缩、生成PDF文件及PDF文件压缩
- win7没有语音识别怎么办|win7系统语音识别设置方法
- cache abstraction
- 电脑变卡DOS解决方案
- 鼠眼看Linux调度器 by raise_sail @ chinaunix
- 月薪过万的运维工程师都要会干什么
- JAVA-多线程 三 {多线程状态}JAVA从基础开始 -- 3
- 【开发技术】2万字分析shiro、spring security两大安全框架,spring session,OAuth2 入门级教程
- ODBC连接达梦数据库
- 每日分享(采集网站访客流量统计程序)