[Java] List的笔记
目标
-
- Javaのコレクションフレームワークの1つである List について、整理してみます。
- 各クラスやメソッドの詳細な説明はしません。
主要的班级
- java.util.ArrayList – 阵列列表
- 具有快速的随机访问速度
- 需要复制数组来添加或删除列表的头部或中间元素,因此速度较慢
java.util.LinkedList – 线性链表
随机访问速度较慢
对列表的头部或中间元素进行添加或删除的操作速度较快
java.util.Vector – 旧的集合框架
基本上每个方法都是同步的
基本上不使用
方便的方法 de
基本上,这些都包含在java.util.Collections类的实用工具类中。
此外,java.util.List(或其父类java.util.Collection)还具有方便的方法。
将数组与其他数据类型相互转换
-
- java.util.Arrays#asList()
- java.util.Collection#toArray()
请参考数组的注释以获取详细信息。
从Enumeration转换成List。
- java.util.Collections#list()
一次性将所有内容加载并转存到列表中。
Properties properties = System.getProperties();
Enumeration<?> keyNames = properties.propertyNames();
List<?> list = Collections.list(keyNames);
for (Object prop : list) {
System.out.println(prop);
}
与Stream的互相转换
-
- java.util.Collection#stream()
java.util.stream.Stream#collect() と java.util.stream.Collectors#toList() の組み合わせ
List<String> list = Arrays.asList("Alfa", "Bravo", "Charlie");
List<String> result = list.stream()
.filter((s) -> s.contains("o"))
.collect(Collectors.toList());
System.out.println(result); // -> "[Bravo]"
从JDK16开始,添加了Strem#toList()方法。这使得我们能够以更短的方式编写代码。
然而,请注意,Strem#toList()会返回一个不可变的列表,这在javadoc中已经明确说明了。
List<String> list = Arrays.asList("Alfa", "Bravo", "Charlie");
List<String> result = list.stream()
.filter((s) -> s.contains("o"))
.toList(); // <- 短く!
System.out.println(result); // -> "[Bravo]"
顺便提一下,关于Collectors#toList()方法,从实现上来看,它返回的是一个可变的列表,但是在javadoc中却注明了”返回的列表的类型、可变性、可序列化性或线程安全性均不被保证”,并不能保证其是可变的。顺带一提,还有一个方法叫Collectors#toUnmodifiableList(),它保证返回一个不可变的列表。
一个空列表
- java.util.Collections#emptyList()
如果需要一个空列表,在不必要地使用 new ArrayList() 来生成实例的情况下,最好重复使用不可变的对象。
请注意它是不可更改的。
- java.util.List#of()
从Java 9开始,可以使用List#of()来创建一个不可更改的空列表。这个方法更简洁。
只能更改一个元素的不可修改列表。
- java.util.Collections#singletonList()
注意,无法进行更改。
- java.util.List#of(E)
从Java 9开始,可以更容易地创建不可更改的单元素列表。这个版本更简短。
无法更改的清单化
- java.util.Collections#unmodifiableList()
非常感谢您在我需要使用常数列表时所提供的帮助。
- java.util.List#of(E…)
从Java 9开始,可以直接创建不可更改的列表。这种方式更简短和易懂。
进行同期列表化
- java.util.Collections#synchronizedList()
动态保证
- java.util.Collections#checkedList()
其他
java.util.Collections#addAll() – まとめて追加
java.util.Collections#copy() – コピー
java.util.Collections#fill() – 値の設定(リストのサイズは変わらない)
java.util.Collections#shuffle() – シャッフル
いろいろ
subList()方法
subList()是一个返回列表的子列表实例的方法,但是子列表的元素与原列表是共享的。
换句话说,如果修改部分列表,主列表也会被修改,反之亦然,如果修改主列表,部分列表也会被修改。
List<String> list = new ArrayList<>();
Collections.addAll(list, "Alfa", "Bravo", "Charlie", "Delta", "Echo", "Foxtrot");
List<String> subList = list.subList(1, 3);
System.out.println(subList); // -> "[Bravo, Charlie]"
subList.set(0, "x");
System.out.println(subList); // -> "[x, Charlie]"
System.out.println(list); // -> "[Alfa, x, Charlie, Delta, Echo, Foxtrot]"
利用这个可以进行列表的部分删除和替换等操作。
List<String> list = new ArrayList<>();
Collections.addAll(list, "Alfa", "Bravo", "Charlie", "Delta", "Echo", "Foxtrot");
list.subList(1, 3).clear();
System.out.println(list); // -> "[Alfa, Delta, Echo, Foxtrot]"
当只需要部分列表时,保留原列表是多余的。因此,在这种情况下,重新创建部分列表可能更好。
public List<String> getXxxList() {
// 巨大なリストを取得してしまった
List<String> hugeList = getHugeList();
// 必要なのは一部だけ
List<String> subList = new ArrayList<>(hugeList.subList(1, 3));
return subList;
}
java.util.RandomAccess接口的中文释义是什么?
如果您自己创建了List类,我认为最好实现RandomAccess接口,以便能够进行随机访问。
对不可变列表进行初始化。
为了实现定值的使用方法,生成不可变列表是相对较常见的。
每次在这种情况下,我经常需要将Collections#unmodifiableList()和Arrays#asList()组合使用,但由于这样写麻烦,所以我经常要创造下面这种方法。
@SafeVarargs
public static <E> List<E> toConstList(E... data) {
int length = (data == null) ? 0 : data.length;
switch (length) {
case 0:
return Collections.emptyList();
case 1:
return Collections.singletonList(data[0]);
default:
return Collections.unmodifiableList(Arrays.asList(data));
}
}
大多数情况下,只需要最后一个默认部分就足够了。
在Java 9中,我们可以立即创建不可更改的列表,这非常方便。
private static final List<String> NAMES = List.of("Foo", "Bar", "Baz");