当我们在Java中将映射的键转换为小写时,有什么简单的方法可以合并值集吗?
Is there any simple way to merge value set when we convert key of map to lower case in Java?
我有一张混合大小写的地图,例如
{a=[v1, V1], A={v2, V2, v3}
我想把所有东西都变成小写,
{a=[v1, v2, v3]}
我在 Java 中详细地做了,想知道是否有 simple/better 方式。谢谢
Map<String, Set<String>> result = new HashMap<>();
for (Map.Entry<String, Set<String>> entry : map.entrySet()) {
String key = entry.getKey().toLowerCase();
Set<String> currSet = entry.getValue().stream().map(v -> v.toLowerCase()).collect(Collectors.toSet());
Set<String> existSet = result.get(key);
if (existSet == null) {
result.put(key, currSet);
} else {
existSet.addAll(currSet);
}
}
您可以利用 putIfAbsent()
或 computeIfAbsent()
来防止不必要的集合实例化,如果还没有值,则在地图上创建一个新集合,然后调用addAll()
Map<String, Set<String>> result = new HashMap<>();
for (Map.Entry<String, Set<String>> entry : map.entrySet()) {
String key = entry.getKey().toLowerCase();
Set<String> currSet = entry.getValue().stream().map(v -> v.toLowerCase()).collect(Collectors.toSet());
result.computeIfAbsent(key, k -> new HashSet<>()).addAll(currSet);
}
putIfAbsent()
类似,但同样,如果值为 actually 不存在,它将始终实例化一个新的 HashSet 而不是仅实例化一个:
result.putIfAbsent(key, new HashSet<>()).addAll(currSet);
如果您是 java-stream 粉丝:
@Test
void mapToMap() {
// Map.of: Java 9 or higher
Map<String, Set<String>> before = Map.of("A", Set.of("A", "a"), "a", Set.of("b", "B", "c"));
// Collectors.toMap: Java 8 or higher
Map<String, Set<String>> after = before.entrySet().stream().collect(
Collectors.toMap(
e -> e.getKey().toLowerCase(),
e -> e.getValue().stream().map(String::toLowerCase).collect(Collectors.toSet()),
(existing, replacement) -> {
existing.addAll(replacement);
return existing;
}
)
);
assertThat(after.size()).isEqualTo(1);
assertThat(after.get("a")).containsExactly("a", "b", "c");
}
你可以这样使用Map.computeIfAbsent()
。
public static void main(String[] args) throws IOException {
Map<String, Set<String>> input = Map.of(
"a", Set.of("v1", "V1"),
"A", Set.of("v2", "V2", "v3"));
Map<String, Set<String>> output = new LinkedHashMap<>();
for (Entry<String, Set<String>> e : input.entrySet())
output.computeIfAbsent(e.getKey().toLowerCase(), k -> new HashSet<>())
.addAll(e.getValue().stream().map(String::toLowerCase).toList());
System.out.println(output);
}
输出:
{a=[v1, v2, v3]}
我有一张混合大小写的地图,例如
{a=[v1, V1], A={v2, V2, v3}
我想把所有东西都变成小写,
{a=[v1, v2, v3]}
我在 Java 中详细地做了,想知道是否有 simple/better 方式。谢谢
Map<String, Set<String>> result = new HashMap<>();
for (Map.Entry<String, Set<String>> entry : map.entrySet()) {
String key = entry.getKey().toLowerCase();
Set<String> currSet = entry.getValue().stream().map(v -> v.toLowerCase()).collect(Collectors.toSet());
Set<String> existSet = result.get(key);
if (existSet == null) {
result.put(key, currSet);
} else {
existSet.addAll(currSet);
}
}
您可以利用 putIfAbsent()
或 computeIfAbsent()
来防止不必要的集合实例化,如果还没有值,则在地图上创建一个新集合,然后调用addAll()
Map<String, Set<String>> result = new HashMap<>();
for (Map.Entry<String, Set<String>> entry : map.entrySet()) {
String key = entry.getKey().toLowerCase();
Set<String> currSet = entry.getValue().stream().map(v -> v.toLowerCase()).collect(Collectors.toSet());
result.computeIfAbsent(key, k -> new HashSet<>()).addAll(currSet);
}
putIfAbsent()
类似,但同样,如果值为 actually 不存在,它将始终实例化一个新的 HashSet 而不是仅实例化一个:
result.putIfAbsent(key, new HashSet<>()).addAll(currSet);
如果您是 java-stream 粉丝:
@Test
void mapToMap() {
// Map.of: Java 9 or higher
Map<String, Set<String>> before = Map.of("A", Set.of("A", "a"), "a", Set.of("b", "B", "c"));
// Collectors.toMap: Java 8 or higher
Map<String, Set<String>> after = before.entrySet().stream().collect(
Collectors.toMap(
e -> e.getKey().toLowerCase(),
e -> e.getValue().stream().map(String::toLowerCase).collect(Collectors.toSet()),
(existing, replacement) -> {
existing.addAll(replacement);
return existing;
}
)
);
assertThat(after.size()).isEqualTo(1);
assertThat(after.get("a")).containsExactly("a", "b", "c");
}
你可以这样使用Map.computeIfAbsent()
。
public static void main(String[] args) throws IOException {
Map<String, Set<String>> input = Map.of(
"a", Set.of("v1", "V1"),
"A", Set.of("v2", "V2", "v3"));
Map<String, Set<String>> output = new LinkedHashMap<>();
for (Entry<String, Set<String>> e : input.entrySet())
output.computeIfAbsent(e.getKey().toLowerCase(), k -> new HashSet<>())
.addAll(e.getValue().stream().map(String::toLowerCase).toList());
System.out.println(output);
}
输出:
{a=[v1, v2, v3]}