HashSet 抛出 UnsupportedOperationException
Posted
技术标签:
【中文标题】HashSet 抛出 UnsupportedOperationException【英文标题】:HashSet throws UnsupportedOperationException 【发布时间】:2022-01-22 23:14:46 【问题描述】:我有下面的代码,当我使用remove
或removeIf
从集合中删除一个项目时,得到一个错误java.lang.UnsupportedOperationException: null
private Set<Speciality> specialities = new HashSet<>();
private void updateSpeciality(SpecialityETAUpdatedEvent evt)
if (CollectionUtils.isNotEmpty(this.specialities))
Optional<Speciality> specialityOptional = this.specialities.stream().filter((Speciality speciality) -> speciality.getCode().equals(evt.code)).findFirst();
if (specialityOptional.isPresent())
this.specialities.remove(specialityOptional.get());// **** Exception thrown here
this.specialities.add(new Speciality().code(evt.code).label(evt.label).startDate(evt.startDate));
java.lang.UnsupportedOperationException: null at java.util.Collections$UnmodifiableCollection.remove(Collections.java:1060) 在 com.xxxx.updateSpeciality(EstablishmentAggregate.java:916) 在 com.xxxx.EstablishmentAggregate.on(EstablishmentAggregate.java:909) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 java.lang.reflect.Method.invoke(Method.java:498)
【问题讨论】:
请参阅minimal reproducible example。您需要使您的代码示例成为我们可以复制/粘贴、运行和观察与您相同的结果;否则我们无法找出导致问题的原因。 您需要提供堆栈跟踪。 解释在你的调用栈中:你的集合是UnmodifiableCollection
;不是HashSet
。你给specialities
分配了什么?
我想知道堆栈跟踪中的“UnmodifiableCollection”...这可能与在发布的代码中创建的 Set
不同 - 包含 minimal reproducible example 的一个原因(例如, Set.of(...)
返回这样一个不可修改的集合)
【参考方案1】:
您确定专业是HashSet
吗?可以在某处创建为不同的类型吗?例如,UnsupportedOperationException
可以扔到不可修改的集合上。
您似乎可以在某处设置specialities
,并使用显式setSpecialities
传递一个Set
,但不是HashSet
。
在这种情况下,实例化 Set 的类不支持 remove
和 removeIf
方法,它们的实现类似于以下代码:
public boolean remove(Object o)
throw new UnsupportedOperationException();
一种创建不可修改Set的方法是例如使用java 9 Set.of
的函数:
返回一个不可变集合包含零个元素
正如 javadoc 中所解释的:
Set.of()
静态工厂方法提供了一种创建不可变集合的便捷方式。这些方法创建的 Set 实例具有以下特点:
它们在结构上是不可变的。不能添加或删除元素。 调用任何 mutator 方法总是会导致抛出 UnsupportedOperationException。但是,如果包含的元素本身是可变的,这可能会导致 Set 行为不一致或其内容似乎发生变化。
【讨论】:
实际的documentation 更加严格:“它们不可修改。”不仅“结构上不可变”(因为没有索引访问或任何其他更改元素的方法,这并不重要:-))【参考方案2】:以下是我将如何在集合中更新或添加条目。
import java.util.*;
class Record
int id, val;
Record(int id) this.id = id;
Record(int id, int val) this.id = id; this.val=val;
public boolean equals(Object o)
return o instanceof Record ? id==((Record)o).id : false;
public int hashCode()
return Objects.hashCode(id);
public String toString()
return String.format("Container[id=%d, val=%d]", id, val);
class RecordSet extends HashSet<Record>
Record addOrUpdate(Record c)
remove(c);
add(c);
return c;
public class Main
public static void main(String[] args)
RecordSet set = new RecordSet();
set.add(new Record(1,100));
set.add(new Record(2,200));
set.add(new Record(3,300));
System.out.println("Before: " + set);
Record c1 = new Record(1,500); //update existing record
Record c2 = new Record(4,400); //new record
set.addOrUpdate(c1);
set.addOrUpdate(c2);
System.out.println("After: " + set);
【讨论】:
以上是关于HashSet 抛出 UnsupportedOperationException的主要内容,如果未能解决你的问题,请参考以下文章