zoukankan      html  css  js  c++  java
  • [改善Java代码]避开基本类型数组转换列表陷阱

     开发中经常用到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的方法说明:输入一个变长参数,返回一个固定长度的列表.

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

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

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

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

    运行输出:

    元素类型: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的输入参数,否则会引起程序逻辑混乱.

  • 相关阅读:
    VS2010开发工具使用技巧<之简单讲解>
    JS中的数学计算<之简单实例讲解>
    让DIV中文字换行显示
    VS2010编写WebService与在IIS的发布<之简单讲解>
    JSON.parse 与 eval() 对于解析json的问题
    [字符串]与[数组]的互相转换
    A标签实现文件下载功能
    "Chinese_PRC_CI_AS" 和 "Chinese_PRC_90_CI_AI" 之间的排序规则冲突问题
    IE开发人员工具之实用功能讲解
    CSS选择器 < ~ +
  • 原文地址:https://www.cnblogs.com/DreamDrive/p/5641065.html
Copyright © 2011-2022 走看看