Collections.list() 将 Enumeration 转为 ArrayList,实现新旧 API 平滑过渡,简化代码并支持现代集合操作。

Collections.list()是 Java 提供的一个便捷方法,它能将一个旧式的
Enumeration接口包装成一个现代的
ArrayList,从而方便我们使用
Collection框架的丰富功能,实现新旧 API 之间的平滑过渡。
解决方案
在 Java 的早期版本中,
Enumeration接口是遍历集合元素的主要方式。你可能会在一些遗留的 API 中遇到它,比如
Hashtable的
elements()或
keys()方法,或者
Vector的
elements()方法。然而,随着 Java 5 引入了泛型和
Iterable接口,以及后来 Java 8 引入的 Stream API,
List接口以及整个
Collection框架提供了更强大、更灵活、更现代的编程范式。
Collections.list()方法的出现,正是为了解决这种新旧 API 之间的“代沟”。它的作用非常直接:接收一个
Enumeration类型的参数,然后遍历这个
Enumeration中的所有元素,并将它们添加到一个新的
ArrayList中并返回。这使得我们能迅速将一个旧式的数据源转换成一个
List,进而可以享用
List提供的诸如
get(index)、
subList()、
sort()等丰富操作,甚至可以方便地将其转换为 Stream 进行链式操作。
来看一个简单的例子,假设我们有一个
Hashtable:
立即学习“Java免费学习笔记(深入)”;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
public class EnumerationToListExample {
public static void main(String[] args) {
Hashtable properties = new Hashtable<>();
properties.put("user", "admin");
properties.put("env", "dev");
properties.put("version", "1.0");
// 获取Enumeration
Enumeration keysEnumeration = properties.keys();
// 使用Collections.list() 转换为List
List keyList = Collections.list(keysEnumeration);
System.out.println("转换后的List: " + keyList);
// 现在可以对List进行各种操作了
keyList.sort(String::compareTo);
System.out.println("排序后的List: " + keyList);
// 或者转换为Stream
keyList.stream().filter(s -> s.startsWith("v")).forEach(System.out::println);
}
} 这个方法虽然简单,但其价值在于提供了一个优雅的桥梁,避免了手动循环
while(enumeration.hasMoreElements())然后
list.add(enumeration.nextElement())这种略显繁琐的写法。它把这种常见的转换模式封装起来,让代码更简洁,意图更明确。
为什么在现代Java开发中更推荐使用List而非Enumeration?
在现代 Java 开发语境下,
Enumeration确实显得有些“老派”。它的局限性非常明显,这使得我们倾向于将其转换为
List或其他
Collection类型。
Enumeration是一个只读、单向的迭代器。你只能向前遍历,不能回溯,也没有提供修改底层集合的方法。这与
Iterator接口的
remove()方法相比,就显得功能单一。更重要的是,
Enumeration不支持泛型。虽然在 Java 5 之后,我们可以通过类型推断或强制转换来使用它,但在定义时它是一个原始类型(raw type),这意味着编译时无法提供类型安全检查,运行时可能出现
ClassCastException。这在强调类型安全的 Java 世界里,无疑是一个短板。
本文档主要讲述的是Android数据格式解析对象JSON用法;JSON可以将Java对象转成json格式的字符串,可以将json字符串转换成Java。比XML更轻量级,Json使用起来比较轻便和简单。JSON数据格式,在Android中被广泛运用于客户端和服务器通信,在网络数据传输与解析时非常方便。希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
此外,
Enumeration的 API 相对贫瘠。它只有
hasMoreElements()和
nextElement()两个方法,功能非常基础。而
List接口,作为
Collection框架的核心成员,拥有极其丰富的 API,比如按索引访问 (
get(index))、添加/删除元素 (
add(),
remove())、查找元素 (
indexOf())、子列表 (
subList()) 等。这些方法极大地提升了我们处理集合数据的效率和灵活性。
再者,
Enumeration与 Java 8 引入的 Stream API 格格不入。Stream API 旨在提供一种声明式、函数式的数据处理方式,它要求数据源是
Iterable或可以转换为
Stream的。
Enumeration本身并不实现
Iterable接口,这意味着你不能直接对其调用
stream()方法。虽然可以通过
Collections.list()转换成
List后再调用
stream(),但这本身就说明了
Enumeration的“不合时宜”。在需要进行复杂的数据过滤、映射、归约等操作时,
List结合 Stream API 的优势是
Enumeration无法比拟的。
所以,将
Enumeration转换为
List,不仅仅是语法上的转换,更是拥抱现代 Java 编程范式,享受更强大、更安全、更灵活的集合操作能力。
Collections.list() 的内部实现机制是怎样的?还有哪些手动转换Enumeration到List的方法?
Collections.list()方法的内部实现其实非常直观,并没有太多魔法。如果你查看 Java 源代码,会发现它大致上就是执行了一个简单的循环:
public staticArrayList list(Enumeration e) { ArrayList list = new ArrayList<>(); // 创建一个新的ArrayList while (e.hasMoreElements()) { // 遍历Enumeration list.add(e.nextElement()); // 将每个元素添加到List中 } return list; // 返回填充好的List }
可以看到,它本质上就是创建了一个新的
ArrayList,然后通过
Enumeration的
hasMoreElements()和
nextElement()方法逐个取出元素并添加到
ArrayList中。这意味着,这个转换过程的时间复杂度是 O(n),其中 n 是
Enumeration中元素的数量。它需要遍历所有元素,并为每个元素执行一次
add()操作。
那么,除了
Collections.list(),我们还有哪些手动转换的方法呢?其实,最直接的方式就是我们上面提到的
Collections.list()内部所做的事情——自己写一个循环。
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
public class ManualEnumerationToListExample {
public static void main(String[] args) {
Hashtable data = new Hashtable<>();
data.put("key1", "value1");
data.put("key2", "value2");
Enumeration keysEnum = data.keys();
// 手动转换方法1:使用while循环
List manualList1 = new ArrayList<>();
while (keysEnum.hasMoreElements()) {
manualList1.add(keysEnum.nextElement());
}
System.out.println("手动转换方法1: " + manualList1);
// 注意:Enumeration是单向的,一旦遍历完就不能再次使用。
// 如果要演示其他方法,需要重新获取Enumeration。
Enumeration keysEnum2 = data.keys();
// 手动转换方法2:如果想更“现代”一点,可以先转为Iterator,再转为List(Java 9+)
// 这种方式通常不会直接用在Enumeration上,因为Collections.list()更直接。
// 但如果有一个老旧的Enumeration,又想用Stream,可以这样:
List manualList2 = new ArrayList<>();
// 假设这里我们重新获取了 keysEnum2
keysEnum2.asIterator().forEachRemaining(manualList2::add);
System.out.println("手动转换方法2 (Java 9+): " + manualList2);
}
} 从性能角度来看,
Collections.list()和手动
while循环的性能几乎是一致的,因为
Collections.list()本质上就是对这种循环的封装。它们都涉及到元素的逐个拷贝。如果你对性能有极致要求,并且知道
Enumeration的大致大小,可以









