固定大小数组实现的集合为何无需实现全部接口方法?附keySet报错疑问
为什么Map的keySet()返回的Set调用addAll会抛出UnsupportedOperationException?
哥们,你踩的这个坑其实是Java集合框架里一个很经典的设计点,咱们一步步拆解明白:
1. Set接口的方法并非强制全部实现
Java里的Set接口继承自Collection接口,而Collection定义的很多修改类方法(比如add()、addAll())属于可选操作。接口只规定了方法的契约,但并没有要求所有实现类必须支持这些操作。如果实现类不支持某个修改行为,就可以直接抛出UnsupportedOperationException,这完全符合Java集合框架的规范。
2. Map.keySet()返回的是「视图集合」,而非独立可修改集合
你调用map1.keySet()得到的Set,本质是原Map的一个视图——它的内容、大小完全绑定原Map,不能独立进行添加或删除操作:
- 试想一下,如果允许你往这个keySet里加一个新字符串,对应的Map里应该存什么value?根本没法确定,所以这种操作从设计逻辑上就不被允许。
- 这类视图集合的修改方法都会被实现为直接抛出异常,比如
HashMap内部的KeySet类,重写的add()方法就是直接抛异常,而addAll()默认会循环调用add(),自然也会触发异常。
3. 正确的合并方式
如果要合并两个Map的key集合,你需要先创建一个可修改的独立Set,比如用HashSet包装原keySet:
Set<String> strings = new HashSet<>(map1.keySet()); strings.addAll(map2.keySet()); // 这里注意你原代码里的`ketSet`是拼写错误哦,应该是`keySet()`
这样创建的HashSet是独立的集合,支持所有Set的修改操作,就不会再抛出异常了。
内容的提问来源于stack exchange,提问作者Ezra-Shimon
相关产品推荐
相关产品推荐

