3

Having a data map as below :

Map<String, List<Integer>> dataMap = ....

i want to convert it to another Map

below, the solution I've tried

Map<String, int[]> dataMapOut = new HashMap<>();
dataMap.entrySet().stream().forEach(entry -> {
    String key = entry.getKey();
    int[] val = entry.getValue().stream().mapToInt(i -> i).toArray();
    dataMapOut.put(key, val);
});

Looking for better and more concise way of mapping ?

2
  • 2
    Question is: why would you want to replace a List with an array? Seems like an XY problem to me. Commented Apr 16, 2018 at 20:15
  • @Turing85 - There is one API which returns Map of List and need to call another API which expects map of int[]; so writing an adapter. Commented Apr 17, 2018 at 17:32

3 Answers 3

10

You're looking for the toMap collector.

 Map<String, int[]> result = dataMap.entrySet()
            .stream()
            .collect(Collectors.toMap(Map.Entry::getKey,
                    e -> e.getValue()
                            .stream()
                            .mapToInt(Integer::intValue)
                            .toArray()));
Sign up to request clarification or add additional context in comments.

2 Comments

Tried exactly same but Eclipse was not auto-suggesting getValue; so I thought I am doing something wrong :(
@javaq I use IntelliJ IDEA so not sure how good the eclipse IDE is. but at least now we know next time eclipse doesn't help you out, maybe you can continue until there is a compilation error.
2

With streams, use Collectors.toMap and Arrays.setAll to create the array from each List:

Map<String, int[]> dataMapOut = dataMap.entrySet().stream()
    .collect(Collectors.toMap(
        Map.Entry::getKey,
        e -> {
            int[] arr = new int[e.getValue().size()];
            Arrays.setAll(arr, e.getValue()::get);
            return arr;
        }));

Without streams, using Map.forEach along with Arrays.setAll:

Map<String, int[]> dataMapOut = new HashMap<>();
dataMap.forEach((k, v) -> {
    int[] arr = new int[v.size()];
    Arrays.setAll(arr, v::get);
    dataMapOut.put(k, arr);
});

Or, if you want to be succinct:

Map<String, int[]> map = new HashMap<>();
dataMap.forEach((k, v) -> map.put(k, v.stream().mapToInt(i -> i).toArray()));

Comments

1

Another solution can be like this:

Map<String,int[]> result= map.entrySet()
        .stream()
        .map(m->new AbstractMap.SimpleImmutableEntry<>(m.getKey(),m.getValue()
                   .stream()
                   .mapToInt(Integer::intValue)
                   .toArray()))
        .collect(Collectors.toMap(Map.Entry::getKey,entry->entry.getValue(),(e1,e2)->e1,LinkedHashMap::new));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.