[改善Java代码]避开基本类型数组转换列表陷阱

时间:2022-08-29 09:55:14

开发中经常用到Arrays和Collections这两个工具类. 在数组和列表之间进行切换.非常方便.但是也会遇到一些问题.

看代码:

import java.util.Arrays;
import java.util.List; public class Client { public static void main(String[] args) {
int[] data = {1,2,3,4,5};
List list = Arrays.asList(data);
System.out.println("列表中的元素数量是:" + list.size());
} }

运行结果:

列表中的元素数量是:1

为什么不是5? 事实上data确实是一个有5个元素的int类型数组,只是通过asList转换列表之后就只有一个元素了.

看Arrays.asList的方法说明:输入一个变长参数,返回一个固定长度的列表.

     /**
* Returns a fixed-size list backed by the specified array. (Changes to
* the returned list "write through" to the array.) This method acts
* as bridge between array-based and collection-based APIs, in
* combination with {@link Collection#toArray}. The returned list is
* serializable and implements {@link RandomAccess}.
*
* <p>This method also provides a convenient way to create a fixed-size
* list initialized to contain several elements:
* <pre>
* List&lt;String&gt; stooges = Arrays.asList("Larry", "Moe", "Curly");
* </pre>
*
* @param a the array by which the list will be backed
* @return a list view of the specified array
*/
@SafeVarargs
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}

asList方法输入的是一个泛型变长参数,我们知道基本类型是不能泛型化的,也就是说8个基本类型不能作为泛型参数,要想作为泛型参数就必须使用其所对应的包装类型,那前面的例子传递了一个int类型的数组,程序为何没有编译报错?

Java中数组是一个对象,它是可以泛型化的,也就说例子中是把一个int类型的数组作为了T的类型,所以转换后在List中就只有一个类型为int数组的元素了.打印出来...

 import java.util.Arrays;
import java.util.List; public class Client { public static void main(String[] args) {
int[] data = {1,2,3,4,5};
List list = Arrays.asList(data);
System.out.println("元素类型:" + list.get(0).getClass());
System.out.println("前后是否相等:"+data.equals(list.get(0)));
} }

运行输出:

元素类型:class [I
前后是否相等:true

放在列表中的元素是一个int数组,为什么"元素类型"后的class是"[I"?  因为JVM不可能输出Array类型,因为Array是属于java.lang.reflect包的,它是通过反射访问数组元素的工具类.在Java中任何一个数组的类都是"[I"(如果是double对应"[D",float对应的是"[F"),究其原因就是Java中并没有定义数组这个类,它是编译器编译的时候生成的,是一个特殊的类,在JDK的帮助中也没有任何数组类的信息.

修改方案,直接使用包装类即可,代码如下:

import java.util.Arrays;
import java.util.List; public class Client { public static void main(String[] args) {
Integer[] data = {1,2,3,4,5};
List list = Arrays.asList(data);
System.out.println("列表中的元素数量是:" + list.size());
} }

运行输出:

列表中的元素数量是:5

仅仅把int变成Integer,即可让输出的元素数量变成5,需要说明的是,不仅仅是int类型的数组有这个问题,其他7个基本类型的数组也都存在相似的问题.

在把基本类型数组转换成列表时,要特别小心asList方法的陷阱,避免出现程序逻辑混乱的情况.

注意:原始类型数组不能作为asList的输入参数,否则会引起程序逻辑混乱.

[改善Java代码]避开基本类型数组转换列表陷阱的更多相关文章

  1. &lbrack;改善Java代码&rsqb;不要让类型默默转换

    建议23:不要让类型默默转换 public class Client { // 光速是30万公里/秒,常量 public static final int LIGHT_SPEED = 30 * 100 ...

  2. &lbrack;改善Java代码&rsqb;提防包装类型的null值

    建议26: 提防包装类型的null值 我们知道Java引入包装类型(Wrapper Types)是为了解决基本类型的实例化问题,以便让一个基本类型也能参与到面向对象的编程世界中.而在Java 5中泛型 ...

  3. &lbrack;改善Java代码&rsqb;用整数类型处理货币

    建议22:用整数类型处理货币. public class Client { public static void main(String[] args) { System.out.println(&q ...

  4. &lbrack;改善Java代码&rsqb;性能考虑,数组是首选

    建议60:性能考虑,数组是首选 一.分析  数组在实际的系统开发中使用的越来越少,我们通常只有在阅读一些开源项目时才会看到它们的身影,在Java中它确实没有List.Set.Map这些集合使用起来方便 ...

  5. &lbrack;改善Java代码&rsqb; 谨慎包装类型的大小比较

    建议27:谨慎包装类型的大小比较 基本数据类型比较大小木有问题,不过其对应的包装类型大小比较就需要注意了.看如下代码: public class Client { public static void ...

  6. &lbrack;改善Java代码&rsqb;不推荐使用binarySearch对列表进行检索

    对一个列表进行检索时,我们使用的最多的是indexOf方法,它简单好用,而且也不会出错,虽然它只能检索到第一个符合条件的值,但是我们可以生成子列表后再检索.这样也就可以查找到所有符合条件的值了. Co ...

  7. 如何使用java代码进行视频格式的转换(FLV)

    如何使用java代码进行视频格式的转换(FLV) 一,前言 在给网页添加视频播放功能后,发现上传的视频有各种格式,那么就需要将他么转换成FLV,以很好的支持在线视频播放. 公司一直在使用中,配合使用, ...

  8. &lbrack;改善Java代码&rsqb;数组的真实类型必须是泛型类型的子类型

    List接口的toArray方法可以把一个结合转化为数组,但是使用不方便,toArray()方法返回的是一个Object数组,所以需要自行转变. toArray(T[] a)虽然返回的是T类型的数组, ...

  9. &lbrack;改善Java代码&rsqb;强制声明泛型的实际类型

    Arrays工具类有一个方法asList可以把一个变长参数或数组变成列表,但是它有一个缺点:它所生成的List长度是不可改变的,而这在我们的项目开发中很不方便. import java.util.Ar ...

随机推荐

  1. Parseval&&num;39&semi;s theorem 帕塞瓦尔定理

    Source: wiki: Parseval's theorem As for signal processing, the power within certain frequency band = ...

  2. 【原】Spark中Client源码分析(一)

    在Spark Standalone中我们所谓的Client,它的任务其实是由AppClient和DriverClient共同完成的.AppClient是一个允许app(Client)和Spark集群通 ...

  3. 机器学习技法:13 Deep Learning

    Roadmap Deep Neural Network Autoencoder Denoising Autoencoder Principal Component Analysis Summary

  4. Thymeleaf中each标签遍历list如何获取index

    <tr th:each="user,userStat:${users}">userStat是状态变量,有 index,count,size,current,even,o ...

  5. TZOJ 5640&colon; 数据结构实验:仓库管理

    描述 某百货公司仓库中有一批电视机,按其价格严格从低到高的次序,以链表(链表含头结点)的形式存储于计算机中,链表的每个结点表示同样价格的电视机台数.现在又有m台价格为x元的电视机准备入库,请将其加入到 ...

  6. &lbrack;Bayesian&rsqb; &OpenCurlyDoubleQuote;我是bayesian我怕谁”系列 - Exact Inference

    要整理这部分内容,一开始我是拒绝的.欣赏贝叶斯的人本就不多,这部分过后恐怕就要成为“从入门到放弃”系列. 但,这部分是基础,不管是Professor Daphne Koller,还是统计学习经典,都有 ...

  7. SQL SERVER发布与订阅

    一.配置分发 1.配置分发服务器,注:配置发布与订阅,连接SQLSERVER必须用服务器名登录 2.配置分发 3.选择分发服务器 4.选择快照文件夹 5.设置此文件夹的读写权限为everyone 6. ...

  8. PostgreSQL9&period;4如何指定数据库schema

    在PostgreSQL中数据库可以有多个schema,在程序访问的时候如果不做特殊的设置,默认连接的是名为public的schema. 那么,如何设置能够让程序去访问特定的schema呢?之前在网上找 ...

  9. 【转载】Android Bug分析系列:第三方平台安装app启动后,home键回到桌面后点击app启动时会再次启动入口类bug的原因剖析

    前言 前些天,测试MM发现了一个比较奇怪的bug. 具体表现是: 1.将app包通过电脑QQ传送到手机QQ上面,点击安装,安装后选择打开app (此间的应用逻辑应该是要触发 [闪屏页Activity] ...

  10. rsync 目录以 &sol; 结尾 轻松同步数据

    命令:#rsync –avz foo/ bar/ 意义:将 foo 目录之下的所有内容,同步到 bar 目录之下.如果不以斜杠结尾,意义就不同了.