Reputation: 952
I am trying to understand the merge method. I have a map of <Character, List<Integer>>
. I want to add the indices to the list of the appropriate key. I want to use the merge method to do so. I tried the following method. I am getting UnsupportedOperationException
. What is the best way to do so using the merge
method?
Map<Character, List<Integer>> map = new HashMap<>();
for (int i = 0; i < s.length(); i++) {
int t = i;
map.merge(s.charAt(i), Arrays.asList(t), (c, list) -> {
map.get(s.charAt(t)).add(t);
return c;
});
}
Upvotes: 3
Views: 450
Reputation: 44368
Wrap Arrays.asList(t)
into new ArrayList<>(...)
to allow its resizing. Arrays.asList
is just a fixed size wrapper that doesn't support adding elements.
Map<Character, List<Integer>> map = new HashMap<>();
for (int i = 0; i < s.length(); i++) {
int t = i;
map.merge(s.charAt(i), new ArrayList<Integer>(Arrays.asList(t)), (c, list) -> {
map.get(s.charAt(t)).add(t);
return c;
});
}
Note that as another answer says, merge
can be replaced with computeIfAbsent
.
If you are into streams, you can use mutable reduction:
Map<Character, List<Integer>> resultMap = IntStream
.range(0, s.length())
.collect(
HashMap::new,
(map, i) -> map.computeIfAbsent(s.charAt(i), ch -> new ArrayList<>()).add(i),
HashMap::putAll
);
Upvotes: 4
Reputation:
You can also use computeIfAbsent()
instead of merge()
like this.
public static void main(String[] args) {
String s = "abcdabcdea";
Map<Character, List<Integer>> map = new HashMap<>();
for (int i = 0; i < s.length(); i++) {
map.computeIfAbsent(s.charAt(i), k -> new ArrayList<>()).add(i);
}
System.out.println(map);
}
output:
{a=[0, 4, 9], b=[1, 5], c=[2, 6], d=[3, 7], e=[8]}
Upvotes: 3