[英]Java - convert unmodifiable sets in a map(key, set) to modifaible
I implemented a function which return Map<key,Set<objects>>
, when I call this function it return the sets with type Unmodifiable.我实现了一个返回
Map<key,Set<objects>>
的 function ,当我调用这个 function 时,它返回类型为不可修改的集合。
I need to do some operations to this sets, how to convert them to modifiable sets in best practice?我需要对这个集合做一些操作,如何在最佳实践中将它们转换为可修改的集合? Otherwise I got
否则我得到
Exception in thread "main" java.lang.UnsupportedOperationException
Thanks in advance.提前致谢。
Assuming that the Map
itself is mutable, you use something like假设
Map
本身是可变的,你使用类似
map.replaceAll((key, set) -> new HashSet<>(set));
Example:例子:
Map<Integer,Set<Object>> map = new HashMap<>();
map.put(5, Collections.emptySet());
map.put(10, Collections.singleton("foo"));
map.replaceAll((key, set) -> new HashSet<>(set));
map.get(5).add(42);
map.get(10).add("bar");
map.entrySet().forEach(System.out::println);
5=[42]
10=[bar, foo]
Of course, you can also replace new HashSet<>(set)
with new TreeSet<>(set)
or generally every Set
implementation type following the copy constructor convention.当然,您也可以将
new HashSet<>(set)
替换为new TreeSet<>(set)
或通常遵循复制构造函数约定的每个Set
实现类型。 When you can't use a copy constructor, you have to resort to addAll
, eg当您不能使用复制构造函数时,您必须求助于
addAll
,例如
map.replaceAll((key, set) -> {
TreeSet<Object> newSet = new TreeSet<>(Comparator.comparing(Object::toString));
newSet.addAll(set);
return newSet;
});
There's another option.还有另一种选择。 Instead of converting all values of the map, only convert the sets on demand, ie when you actually want to modify them and they turn out not to have the intended type:
与其转换 map 的所有值,不如仅按需转换集合,即当您实际想要修改它们但结果却没有预期的类型时:
Map<Integer,Set<Object>> map = new HashMap<>();
map.put(5, Collections.emptySet());
map.put(10, Collections.singleton("foo"));
map.computeIfPresent(5, (key,set)->set instanceof HashSet? set: new HashSet<>()).add(42);
map.computeIfPresent(10, (key,set)->set instanceof HashSet?set:new HashSet<>()).add("bar");
map.entrySet().forEach(System.out::println);
You could copy the original set to another one that can be modified .您可以将 原始集复制到另一个可以修改的集。
Something like this:像这样的东西:
Set<YourType> newSet = unmodifiableSet
.stream()
.collect(Collectors.toSet());
// Or maybe...
Set<YourTYpe> otherSet = new HashSet<>();
otherSet.addAll(unmodifiableSet);
Then, you could modify the new list without any problem, and re-assign it into the map.然后,您可以毫无问题地修改新列表,并将其重新分配到 map。
For a HashSet
:对于
HashSet
:
Set<Type> modifiable = new HashSet<>(unmodifiable);
For a TreeSet
:对于
TreeSet
:
SortedSet<Type> modifiable = new TreeSet<>(unmodifiable);
For a LinkedHashSet
:对于
LinkedHashSet
:
Set<Type> modifiable = new LinkedHashSet<>(unmodifiable);
If you use a fancy Set implementation without such constructor:如果您使用没有此类构造函数的精美 Set 实现:
Set<Type> modifiable = new MyFancySet<>();
modifiable.addAll(unmodifiable);
You can do that as a one-liner with Streams
:您可以使用
Streams
执行此操作:
With map
being your original map (eg Map<Integer, ImmutableSet<Object>> map;
) map
是您原来的 map (例如Map<Integer, ImmutableSet<Object>> map;
)
Map<Integer, Set<Object>> mutableMap = map.entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getKey, Sets::newHashSet));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.