拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 Arrays.asList() 与Collections.singletonList()

Arrays.asList() 与Collections.singletonList()

白鹭 - 2022-08-08 2385 0 2

一、概述

List是我们使用Java 时常用的集合类型。

众所周知,我们可以很容易地在一行中初始化一个List例如,当我们想要初始化一个只有一个元素的List时,我们可以使用Arrays.asList()方法或Collections.singletonList()方法。

在本教程中,我们将讨论这两种方法之间的区别。然后,为简单起见,我们将使用单元测试断言来验证某些操作是否按预期运行。

2.Arrays.asList()方法

首先,Arrays.asList()方法返回一个固定大小的列表

任何结构更改都会抛出UnsupportedOperationException,例如,向列表中添加新元素或从列表中删除元素。现在,让我们通过测试来检查一下:

List<String> arraysAsList = Arrays.asList("ONE");
 assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(
 () -> arraysAsList.add("TWO")
 );

如果我们试一试,测试就通过了。在上面的代码中,我们使用Assertj 的异常断言来验证当我们尝试向列表中添加新元素时是否抛出UnsupportedOperationException

即使我们不能在列表上调用add()remove()操作,我们也可以使用set()方法更改列表中的元素

arraysAsList.set(0, "A brand new string");
 assertThat(arraysAsList.get(0)).isEqualTo("A brand new string");

这一次,我们用一个新的String对象设置列表中的元素。如果我们执行测试,它就会通过。

最后我们来讨论一下Arrays.asList()方法的数组和返回的列表的关系。

正如方法名称所暗示的,此方法使数组作为List工作。让我们了解“使数组作为List工作”的含义。

Arrays.asList()方法返回一个由给定数组支持的List对象也就是说,该方法不会将数组中的元素复制到新的List对像中。相反,该方法提供给定数组的List视图。因此,我们对数组所做的任何更改都将在返回的列表中可见。同样,对列表所做的更改也将在数组中可见:

String[] theArray = new String[] { "ONE", "TWO" };
 List<String> theList = Arrays.asList(theArray);
 //changing the list, the array is changed too
 theList.set(0, "ONE [changed in list]");
 assertThat(theArray[0]).isEqualTo("ONE [changed in list]");
 //changing the array, the list is changed too
 theArray[1] = "TWO [changed in array]";
 assertThat(theList.get(1)).isEqualTo("TWO [changed in array]");

测试通过。因此,对于数组和返回的列表,如果我们在一侧进行了一些更改,那么另一侧也会发生更改。

3.Collections.singletonList()方法

首先,singletonList()方法返回的列表只有一个元素。Arrays.asList()方法不同,singletonList()返回一个不可变列表

换句话说,不允许对singletonList().一个测试可以快速说明这一点:

List<String> singletonList = Collections.singletonList("ONE");
 assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(
 () -> singletonList.add("TWO")
 );
 assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(
 () -> singletonList.set(0, "A brand new string")
 );

如果我们运行测试,它就会通过。因此,无论我们是向列表中添加元素还是更改列表中的元素,它都会抛出UnsupportedOperationException.

值得一提的是,如果我们看一下返回列表类的源代码,与其他List实现不同,返回列表中的单个元素不存储在数组或任何其他复杂的数据结构中。相反,列表直接保存元素对象

private static class SingletonList<E> extends AbstractList<E> implements RandomAccess, Serializable {
 ...
 private final E element;
 SingletonList(E obj) {element = obj;}
 ...
 }

因此,它将占用更少的内存。

4. 简短总结

最后,让我们将Arrays.asList()方法和Collections.singletonList()方法的特点总结在一个表格中,以便更好地概览:


Arrays.asList()Collections.singletonList()
结构变化不允许不允许
非结构性变化允许不允许
数据结构由阵列支持直接握住元素

5. 结论

在这篇快速文章中,我们讨论了Arrays.asList()方法和Collections.singletonList()方法。

当我们想初始化一个只有一个元素的固定大小的列表时,我们可以考虑使用Collections.singletonList()方法。但是,如果需要更改返回列表中的元素,我们可以选择Arrays.asList()方法。


标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *