Java - 将map(key, set)中不可修改的集合转换为可修改的。

问题描述 投票:0回答:1

我实现了一个函数,返回 Map<key,Set<objects>> 当我调用这个函数时,它返回的是类型为Unmodifiable的集合,我需要对这些集合进行一些操作,如何将它们转换为可修改的集合?

我需要对这些集合进行一些操作,如何将它们转换为可修改的集合才是最佳实践?否则我得到

Exception in thread "main" java.lang.UnsupportedOperationException

谢谢。

java collections set guava unmodifiable
1个回答
1
投票

假设 Map 本身是可变的,你可以使用类似

map.replaceAll((key, set) -> new HashSet<>(set));

例子。

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]

当然,你也可以用 new HashSet<>(set)new TreeSet<>(set) 或一般 Set 实现类型遵循复制构造函数的约定。当你不能使用复制构造函数时,你必须使用 addAll例如:

map.replaceAll((key, set) -> {
    TreeSet<Object> newSet = new TreeSet<>(Comparator.comparing(Object::toString));
    newSet.addAll(set);
    return newSet;
});

还有一种选择。不是转换地图的所有值,而是只在需求时转换集合,即当你真正想修改它们,结果发现它们没有预期的类型。

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);

0
投票

你可以复制 变成另一个可以修改的集子.

类似这样。

Set<YourType> newSet = unmodifiableSet
                        .stream()
                        .collect(Collectors.toSet());
// Or maybe...
Set<YourTYpe> otherSet = new HashSet<>();
otherSet.addAll(unmodifiableSet);

然后,你就可以顺利地修改新的列表,并将其重新分配到地图中。


0
投票

只要使用复制构造函数

对于一个 HashSet:

Set<Type> modifiable = new HashSet<>(unmodifiable);

用于: TreeSet:

SortedSet<Type> modifiable = new TreeSet<>(unmodifiable);

用于: LinkedHashSet:

Set<Type> modifiable = new LinkedHashSet<>(unmodifiable);

如果你使用了一个花哨的Set实现,而没有这样的构造函数。

Set<Type> modifiable = new MyFancySet<>();
modifiable.addAll(unmodifiable);

0
投票

你可以把它作为一个单行线,用 Streams:

map 作为你的原始地图 Map<Integer, ImmutableSet<Object>> map;)

Map<Integer, Set<Object>> mutableMap = map.entrySet()
                .stream()
                .collect(Collectors.toMap(Map.Entry::getKey, Sets::newHashSet));
© www.soinside.com 2019 - 2024. All rights reserved.