2018-12-25 Arrays.asList()

2018-12-25  本文已影响0人  光滑的哈士奇

先上源码:

   /**
     * 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 <T> the class of the objects in the array
     * @param a the array by which the list will be backed
     * @return a list view of the specified array
     */
    @SafeVarargs
    @SuppressWarnings("varargs")
    public static <T> List<T> asList(T... a) {
        return new ArrayList<>(a);
    }

最近的项目中有个地方需要将当前数组转换成list,并判断里面是否包含某个数:

 private boolean containsColor(int[] colors, int color) {
        // 1. Erroe: return Arrays.asList(colors).contains(color);

        /* 2. Right: 
          for (int paletteColor : colors) {
            if (paletteColor == color) {
                return true;
            }
        }
        return false;*/

        // 3. Right
        Integer[] integers  = Arrays.stream(colors).boxed().toArray(Integer[]::new);
        List arrayList = Arrays.asList(integers);
        return Arrays.asList(arrayList).contains(color);
    }

最初使用方法一:
结果一直是 false,debug后发现 Arrays.asList() 生成的 List size为1,
list.get(0)结果为color数组;
知道原因所在,改为二,成功;
想追跟究底,继续尝试 + 百度,找到了方法三,成功;
其中发现 size 一直是1,原因在于在Arrays.asList中,接受一个变长参数,一般可看做数组参数,但是因为int[] 本身就是一个类型,所以colors作为参数传递时,编译器认为只传了一个变量,这个变量的类型是int数组,所以size为1。基本类型是不能作为泛型的参数,按道理应该使用包装类型,但这里却没有报错,因为数组是可以泛型化的,所以转换后在list中就有一个类型为int的数组,所以该方法体现的适配器模式,只是转换接口,后台的数据还是那个数组,这也很好的解释了
(一)为什么该方法将数组与列表链接起来,当更新其中之一时,另一个自动更新。
(二)该方法目前对基本类型(byte,short,int,long,float,double,boolean)的支持并不太好。
另外使用该方法还需要注意:
(三)该方法生成的list长度固定,所以不支持影响list长度的操作(add,remove等),支持一些修改操作(set等)。
所以 Arrays.asList 方法适合已有数组数据或者一些元素,而需要快速构建一个List,只用于读取操作,而不用于添加或者删除数据。
如果是想将一个数组转化成一个列表并做增加删除操作的话,可以使用:

List<WaiterLevel> levelList = new ArrayList<WaiterLevel>(Arrays.asList("a", "b", "c"));

另,附上Java8中简化List<Integer>和int[],List<String>和String[]的方法:

上一篇下一篇

猜你喜欢

热点阅读