210810-实战小技巧2:数组与list互转

文章目录
  1. I. 数组转List
    1. 1. Array.asList
      1. 1.1 知识点
    2. 2. new ArrayList
      1. 2.1 避雷预警
    3. 3. Collections.addAll
  2. II. 列表转数组
  3. III. 小结
  4. IV. 其他
    1. 1. 一灰灰Blog: https://liuyueyi.github.io/hexblog
    2. 2. 声明
    3. 3. 扫描关注

每天一个实战小技巧:数组与list互转

这个考题比较常见,也比较简单,难道就这也有什么可以说到的门路不成?

接下来本文好好的说一说它的几种实现姿势,总有一款你喜欢的

I. 数组转List

1. Array.asList

这个考题太简单了,直接使用Array.asList不就完事了么,比如

1
2
3
4
5
6
@Test
public void ary2list() {
String[] ary = new String[]{ "1", "a"};
List<String> list = Arrays.asList((ary);
System.out.println(list);
}

数组转list,so easy!!!

真的就这么简单么???

且看下面这一段代码

1
2
3
4
5
6
7
8
public void ary2list() {
String[] ary = new String[]{ "1", "a"};
List<String> list = Arrays.asList((ary);
System.out.println(list);

list.add("c");
System.out.println(list);
}

直接抛出了异常java.lang.UnsupportedOperationException

有兴趣的小伙伴可以看一下源码实现方式,通过Arrays.asList创建的List,虽说也命名是ArrayList,但是它的全路径为 java.util.Arrays.ArrayList, 不支持add, remove等操作(所以下次再有面试官问ArrayList的知识点时,就可以反问一句,老哥你指的是哪个ArrayList😝,逼格是不是立马拉起来)

1.1 知识点

  • 通过Arrays.asList创建的列表,不允许新增,删除元素;但是可以更新列表中元素的值

2. new ArrayList

上面的数组转list方式虽然是最简单的,但不一定是合适的,特别是当我们可能对转换后的list进行操作时,可能埋坑(而且这种坑还非常隐晦,代码层面上很难发现)

为了减少在代码里面下毒的可能性,不妨使用下面这种方式new ArrayList<>(Arrays.asList(ary))

1
2
3
4
String[] ary = new String[]{ "1", "a"};
List<String> out = new ArrayList<>(Arrays.asList(ary));
out.add("hello");
System.out.println(out);

通过上面这种方式创建的List,就是我们熟知的ArrayList

2.1 避雷预警

看到上面这个使用姿势,就很容易想到一个常见的踩雷点,比如我们的应用中,有一个全局共享的配置列表,张三需要拿id为奇数的配置,李四拿id为偶数的配置,然后他们都是这么做的

1
list.removeIf(s -> s.id % 2 == 0);

然后跑了一次之后发现这个全局的列表清空了,这就是典型的没有做好资源隔离的case了,针对这种场景,要么是限制使用方,直接针对全局的资源进行修改,要么就是使用方拿到的是一个隔离的备份

禁止修改:

  • 使用不可变的容器,如前面提到的java.util.Arrays.ArrayList ()
  • 使用Collections.unmodifiableList创建
1
List<String> unModifyList = Collections.unmodifiableList(out);

列表拷贝

1
new ArrayList<>(Arrays.asList(ary));

(上面这种属于深拷贝的实现,具体可以看一下jdk的源码实现)

3. Collections.addAll

第三种方式借助jdk提供的容器工具类Collections来实现

1
2
3
4
5
6
7
8
9
10
11
12
@Test
public void ary2listV3() {
String[] ary = new String[]{ "1", "a"};
// 创建列表,并指定长度,避免可能产生的扩容
List<String> out = new ArrayList<>(ary.length);
// 实现数组添加到列表中
Collections.addAll(out, ary);

// 因为列表为我们定义的ArrayList,因此可以对它进行增删改
out.add("hello");
System.out.println(out);
}

原则上是比较推荐这种方式来实现的,至于为啥?看下源码实现

1
2
3
4
5
6
public static <T> boolean addAll(Collection<? super T> c, T... elements) {
boolean result = false;
for (T element : elements)
result |= c.add(element);
return result;
}

这段代码的实现是不是非常眼熟,如果让我们自己来写,也差不多会写成这样吧,简单直观高效,完美

II. 列表转数组

不同于数组转列表的几种玩法,列表转数组就简单多了,直接调用List.toArray

1
2
3
4
5
6
7
List<String> list = Arrays.asList("a", "b", "c");
// 返回的是Object[] 数组
Object[] cell = list.toArray();

// 如果需要指定数组类型,可以传一个指定各类型的空的数组
// 也可以传一个与目标列表长度相等的数组,这样会将列表中的元素拷贝到这个数组中
String[] strCell = list.toArray(new String[]{});

III. 小结

今天的博文主题是数组与列表的互转,虽说题目简单,但是实现方式也是多种,需要搞清楚它们之间的本质区别,一不小心就可能采坑,而最简单的地方掉坑里,往往是最难发现和爬出来的

核心知识点小结如下

数组转list:

  • Arrays.asList(xxx):创建的是不可变列表,不能删除和新增元素
  • new ArrayList<>(Arrays.asList(xxx): 相当于用列表创建列表,属于深拷贝的一种表现,获取到的列表支持新增、删除
  • 推荐写法 Collections.addAll()

列表转数组

  • list.toArray: 如果需要指定数组类型,则传参指定

IV. 其他

1. 一灰灰Bloghttps://liuyueyi.github.io/hexblog

一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛

2. 声明

尽信书则不如,以上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激

3. 扫描关注

一灰灰blog

QrCode

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×