0

我实现了一个返回函数Map<key,Set<objects>>,当我调用这个函数时,它返回类型为不可修改的集合。

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

Exception in thread "main" java.lang.UnsupportedOperationException

提前致谢。

4

4 回答 4

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);
于 2020-05-20T13:20:32.247 回答
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);
于 2020-05-19T15:26:47.640 回答
0

您可以将原始集复制到另一个可以修改的集。

像这样的东西:

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

然后,您可以毫无问题地修改新列表,并将其重新分配到地图中。

于 2020-05-19T15:12:05.843 回答
0

您可以使用以下方法作为单线器来做到这一点Streams

map成为您的原始地图(例如Map<Integer, ImmutableSet<Object>> map;

Map<Integer, Set<Object>> mutableMap = map.entrySet()
                .stream()
                .collect(Collectors.toMap(Map.Entry::getKey, Sets::newHashSet));
于 2020-05-19T15:43:00.713 回答