Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java8 stream style to convert a key-value list to a map?

Tags:

I want to convert a list like [k1, v1, k2, v2] to a map like {k1: v1, k2: v2}. The original code is:

List<Object> params = Arrays.asList("k1", "v1", "k2", "v2");
Map<String, Object> map = new HashMap<>();
for(int i = 0; i < params.size(); i+=2) {
    String key = (String)params.get(i);
    Object value = params.get(i + 1);
    map.put(key, value);
}
System.out.println(map); // => {k1=v1, k2=v2}

Then I want to transform it to java8 stream style? How?

like image 503
Run Avatar asked Feb 15 '17 17:02

Run


2 Answers

You can use this, but frankly, your for loop is much more readable. I would try to avoid producing such a list in the first place, and have a List<SomePair> instead, where SomePair contains the key and the value.

    List<Object> params = Arrays.asList("k1", "v1", "k2", "v2");
    Map<String, Object> map =
        IntStream.range(0, params.size() / 2)
                 .collect(HashMap::new,
                          (m, i) -> m.put((String) params.get(i * 2), params.get(i * 2 + 1)),
                          HashMap::putAll);

    System.out.println(map); // => {k1=v1, k2=v2}
like image 71
JB Nizet Avatar answered Sep 22 '22 10:09

JB Nizet


Alternatively to using Stream, you could just use a good-old Iterator and call next to get the next element. Of course, this will fail if the list does not have an even number of elements.

Map<String, Object> map = new HashMap<>();
Iterator<Object> iter = params.iterator();
iter.forEachRemaining(x -> map.put((String) x, iter.next()));
like image 38
tobias_k Avatar answered Sep 22 '22 10:09

tobias_k