You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中如何将Set复制到List?为何此代码无编译错误?

为什么new ArrayList<>(HashMap.keySet())能正常编译运行?

嘿,你的疑惑其实挺常见的——乍一看Set和List是两个不同的集合类型,好像没法直接转换,但这段代码能跑通的关键在于ArrayList的构造器设计和集合接口的继承关系,咱们一步步拆解:

1. HashMap.keySet()的返回类型本质是Collection的子类型

没错,HashMap.keySet()返回的是Set<K>,但你别忘了:Set接口是继承自Collection接口的!也就是说,Set<String>本身就是Collection<String>的一种实现,完全符合Collection类型的定义。

2. ArrayList有一个接受Collection的构造器

ArrayList提供了一个重载构造器:

public ArrayList(Collection<? extends E> c)

这个构造器的作用是把传入的Collection中的所有元素,复制到新创建的ArrayList实例中。这里的泛型参数<? extends E>表示:只要传入的集合元素是E的子类(或者E本身),就可以被接受。

当你写new ArrayList<String>(map.keySet())时,map.keySet()返回的Set<String>正好满足Collection<? extends String>的要求——因为String的子类就是它自己,所以完全匹配构造器的参数类型。

举个实际运行的例子

比如你写这段代码:

HashMap<String, Integer> myMap = new HashMap<>();
myMap.put("apple", 1);
myMap.put("banana", 2);
List<String> keyList = new ArrayList<>(myMap.keySet());

运行后,keyList会包含"apple"和"banana"(不过注意:HashMap的keySet是无序的,所以list里的元素顺序不固定)。

澄清你的误解

你担心的“Set和List不兼容”是指不能直接把Set实例赋值给List类型的变量(比如List<String> list = myMap.keySet();这行代码肯定会编译错误),但咱们的代码是通过ArrayList的构造器,把Set里的元素“转移”到了新的ArrayList中,这是完全合法的操作——本质是集合间的元素复制,而非类型强制转换。

内容的提问来源于stack exchange,提问作者Roger Kim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:58:21