以下Java代码示例List分可变的,不可变的两种:
1、可变
ArrayList 是 List 的可变实现
@Test
public void arrayList()
{
// Mutable
List<String> list = new ArrayList<>();
list.add("?"); // Works
Assertions.assertEquals(List.of("?"), list);
}
LinkedList 是 List 的可变实现
@Test
public void linkedList()
{
// Mutable
List<String> list = new LinkedList<>();
list.add("?"); // Works
Assertions.assertEquals(List.of("?"), list);
}
CopyOnWriteArrayList 是 List 的可变和线程安全实现。
@Test
public void copyOnWriteArrayList()
{
// Mutable
List<String> list = new CopyOnWriteArrayList<>();
list.add("?"); // Works
Assertions.assertEquals(List.of("?"), list);
}
Arrays.asList()返回一个可变但不可增长的 List 实现。
这意味着您可以将 List 中的元素设置为不同的值,但不能添加或删除 List 中的元素。List 的这种实现类似于 Java 数组。
@Test
public void arraysAsList()
{
// Mutable but not growable
List<String> list = Arrays.asList("?");
list.set(0, "??"); // Works
Assertions.assertThrows(
UnsupportedOperationException.class,
() -> list.add(0, "??"));
Assertions.assertEquals(List.of("??"), list);
}
Collections.synchronizedList 返回一个 "有条件线程安全 "的 List 实例。
所谓 "有条件线程安全",是指像 iterator、stream 和 parallelStream 这样的方法是不安全的,开发者必须使用显式锁对其进行保护。
@Test
public void collectionsSynchronizedList()
{
// Mutable
List<String> arrayList = new ArrayList<>();
arrayList.add("?");
// Mutable and "Conditionally Thread-safe"
List<String> list = Collections.synchronizedList(arrayList);
Assertions.assertEquals(List.of("?"), list);
list.add("?");
Assertions.assertEquals(List.of("?", "?"), list);
}
Stream.collect(Collectors.toList()) 将返回一个可变的 List。
@Test
public void streamCollectCollectorsToList()
{
// Mutable
List<String> list = Stream.of("?")
.collect(Collectors.toList());
list.add("?");
Assertions.assertEquals(List.of("?", "?"), list);
}
2、不可变
Collections.emptyList() 返回不可变的空 List。
@Test
public void collectionsEmptyList()
{
// Immutable
List<String> list = Collections.emptyList();
Assertions.assertThrows(
UnsupportedOperationException.class,
() -> list.add(0, "??"));
Assertions.assertEquals(List.of(), list);
}
Collections.singletonList() 返回不可变的单例 List。
@Test
public void collectionsSingletonList()
{
// Immutable
List<String> list =
Collections.singletonList("?");
Assertions.assertThrows(
UnsupportedOperationException.class,
() -> list.add("??"));
Assertions.assertEquals(List.of("?"), list);
}
Collections.unmodifiableList() 返回 List 的 "不可修改视图",
但正如下面的代码所示,它所封装的 List 可以单独修改。它所封装的 List 可以是可变的,也可以是不可变的,但如果是不可变的,视图就是多余的了。
@Test
public void collectionsUnmodifiableList()
{
// Mutable
List<String> arrayList = new ArrayList<>();
arrayList.add("?");
// "Unmodifiable" but arrayList is still Mutable
List<String> list = Collections.unmodifiableList(arrayList);
Assertions.assertThrows(
UnsupportedOperationException.class,
() -> list.add("??"));
Assertions.assertEquals(List.of("?"), list);
arrayList.add("??");
Assertions.assertEquals(List.of("?", "??"), list);
}
List.of() 返回不可变的 List。
@Test
public void listOf()
{
// Immutable
List<String> list = List.of("?");
Assertions.assertThrows(
UnsupportedOperationException.class,
() -> list.add("??"));
Assertions.assertEquals(List.of("?"), list);
}
List.copyOf() 复制另一个 List 的内容,并返回一个不可变的 List。
@Test
public void listCopyOf()
{
// Immutable
List<String> list = List.copyOf(new ArrayList<>(List.of("?")));
Assertions.assertThrows(
UnsupportedOperationException.class,
() -> list.add("??"));
Assertions.assertEquals(List.of("?"), list);
}
Stream.toList() 返回不可变的 List。
@Test
public void streamToList()
{
// Immutable
List<String> list = Stream.of("?").toList();
Assertions.assertThrows(
UnsupportedOperationException.class,
() -> list.add("??"));
Assertions.assertEquals(List.of("?"), list);
}
Stream.collect(Collectors.toUnmodifiableList()) 将返回一个不可修改的 List
它实际上是不可变的,因为没有人能轻易获得它所封装的可变 List 的指针。
@Test
public void streamCollectCollectorsToUnmodifiableList()
{
// Mutable
List<String> list = Stream.of("?")
.collect(Collectors.toUnmodifiableList());
Assertions.assertThrows(
UnsupportedOperationException.class,
() -> list.add("??"));
Assertions.assertEquals(List.of("?"), list);
}