I have a map with mixed cases, e.g.
{a=[v1, V1], A={v2, V2, v3}
I'd like to make everything to lowerCase,
{a=[v1, v2, v3]}
I did it verbosely in Java, wondering whether is any simple/better way. Thanks
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);
}
}
CodePudding user response:
You could utilize putIfAbsent()
, or computeIfAbsent()
to prevent an unnecessary instantiation of a set, on the map to create a new set if there isn't a value yet, and then just call 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()
is similar, but again, it will always instantiate a new HashSet instead of only instantiating one if the value is actually absent:
result.putIfAbsent(key, new HashSet<>()).addAll(currSet);
CodePudding user response:
In case you are a java-stream fan:
@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");
}
CodePudding user response:
You can use Map.computeIfAbsent()
like this.
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);
}
output:
{a=[v1, v2, v3]}