anupamD
anupamD

Reputation: 952

How can I use merge method in Java to append elements to the list value in map<Character,List<Integer>>?

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

Answers (2)

Nikolas
Nikolas

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

user4910279
user4910279

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

Related Questions