乐趣区

关于java:作为Java程序员你真的了解javautilArrays么

嗨~ 大家周末欢快啊,我是阿壮,一个 Java 程序员,最近在工作之余,即没 bug 要改了,也没需要了,又不能让老板看到本人在摸鱼,无聊的我开始 ctrl+ 鼠标左键,漫无目的的看着眼前的 JDK 源码。明天来更大家分享以下我遇到过的 java.util.Arrays 下的坑。

次要剖析三个问题,并给出对于的解决方案

  1. 通过 asList 返回的固定大侠的 List 不反对增加元素
  2. 对原始数组的批改会影响到咱们取得的那个 List
  3. 不能间接应用 Arrays.asList 来转换根本类型数组

请容许我应用巨佬 Java 之父 James Gosling 写的 JDK 源码作为明天的开始。

通过 asList 返回的固定大侠的 List 不反对增加元素

代码

public static void main(String[] args) {String[] arr = new String[]{"aa", "bb"};
        List<String> list = Arrays.asList(arr);
        list.add("cc");
    }

执行后果

Exception in thread "main" java.lang.UnsupportedOperationException
    at java.util.AbstractList.add(AbstractList.java:148)
    at java.util.AbstractList.add(AbstractList.java:108)
    at Test.main(Test.java:8)

起因是 java.util.Arrays.ArrayList 类实现了 set(),get(),contains()办法,然而并没有实现减少元素的办法(事实上是能够调用 add 办法,然而没有具体实现,仅仅抛出 UnsupportedOperationException 异样),因而它的大小也是固定不变的。能够通过 set 办法进行设置值,默认长度是 10。

解决方案

新建一个 ArrayList

代码:

public static void main(String[] args) {String[] arr = {"aa", "bb", "cc"};
        List<String> list = Arrays.asList(arr);
        ArrayList<String> strings = new ArrayList<>(list);
        strings.add("dd");
        System.out.println(strings.toString());
    }

执行后果:

[aa, bb, cc, dd]

通过汇合工具类 Collections.addAll()办法(最高效,举荐)

通过 Collections.addAll(arrayList, strArray)形式转换,依据数组的长度创立一个长度雷同的 List,而后通过 Collections.addAll()办法,将数组中的元素转为二进制,而后增加到 List 中,这是最高效的办法。

代码:

public static void main(String[] args) {String[] arr = {"aa", "bb", "cc"};
        ArrayList<String> strings = new ArrayList<>(arr.length);
        Collections.addAll(strings, arr);
        strings.add("dd");
        System.out.println(strings.toString());
    }

执行后果:

[aa, bb, cc, dd]

Stream 优雅的写法

代码:

public static void main(String[] args) {String[] arr = {"aa", "bb", "cc"};
        List<String> list = Stream.of(arr).collect(Collectors.toList());
        list.add("dd");
        System.out.println(list.toString());
    }

执行成果:

[aa, bb, cc, dd]

底层先将数组转换为流,再应用 addAll()的形式,执行效率次于 Collections.addAll() 形式,然而写法优雅呀。

对原始数组的批改会影响到咱们取得的那个 List

代码

 public static void main(String[] args) {String[] arr = {"aa", "bb", "cc"};
        List<String> list = Arrays.asList(arr);
        arr[1] = "dd";
        System.out.printf("arr:%s list:%s", Arrays.toString(arr), list);
    }

执行后果

arr:[aa, dd, cc] list:[aa, dd, cc]

起因是 Arrays 外部类 ArrayList 其实是间接应用了原始的数组,把通过 Arrays.asList 取得的 List 交给其余办法解决,很容易因为共享了数组,互相批改产生 Bug。

不能间接应用 Arrays.asList 来转换根本类型数组

代码

public static void main(String[] args) {int[] arr = {1, 2, 3};
        List list = Arrays.asList(arr);
        System.out.println(list.size());
    }

执行后果

1

起因是 asList 办法的参数必须是对象或者对象数组,而原生数据类型不是对象,当传入一个原生数据类型数组时,asList 的真正失去的参数就不是数组中的元素,而是数组对象自身。

解决方案

Java8 可通过 stream 流将 3 种根本类型数组转为 List

如果 JDK 版本在 1.8 以上,能够应用流 stream 来将下列 3 种数组疾速转为List,别离是int[]long[]double[],其余数据类型比方short[]byte[]char[],在 JDK1.8 中暂不反对。

代码:

public static void main(String[] args) {int[] arr = {1, 2, 3};
        List<Integer> list = Arrays.stream(arr).boxed().collect(Collectors.toList());
        System.out.println(list);
    }

执行成果:

[1, 2, 3]

我是阿壮,一个后端程序员,微信搜一搜:科技猫,继续分享原创编程技术,实用软件,科技资讯,咱们下期间

退出移动版