This article is participating in “Java Theme Month – Java Debug Notes Event”, see < Event link > for more details.

Question: How do Java 8 lists and streams map

I have a List<Item> collection. I need to convert it to Map <Integer, and the key of the Item> Map must be the index of the Item in the collection. I don’t know how to do this using a stream. Like:

items.stream().collect(Collectors.toMap(...) );Copy the code

Is there anything I can do for you?

Since this problem has been identified as potentially repetitive, I need to add that my specific question is – how do I get the position of the item in the list and use it as a key

Answer 1:

You can use IntStream to create index streams and then convert them to maps:

Map<Integer,Item> map = 
    IntStream.range(0,items.size())
             .boxed()
             .collect(Collectors.toMap (i -> i, i -> items.get(i)));
Copy the code

Answer 2:

For completeness, another solution is to use your own Collector:

public static<T> Collector<T, ? , Map<Integer, T>> toMap() {return Collector.of(HashMap::new, (map, t) -> map.put(map.size(), t), 
            (m1, m2) -> {
                int s = m1.size();
                m2.forEach((k, v) -> m1.put(k+s, v));
                return m1;
            });
}
Copy the code

The usage method is as follows:

Map<Integer, Item> map = items.stream().collect(toMap());

Copy the code

The solution supports concurrent operations and is source-independent (you can use lists without randomly accessing files.lines () or doing anything else).

Answer 3:

You don’t have to feel like you have to do everything in/with the flow. I will do this:

AtomicInteger index = new AtomicInteger();
items.stream().collect(Collectors.toMap(i -> index.getAndIncrement(), i -> i));
Copy the code

As long as you don’t parallelize streams, it works fine and avoids the potential overhead and/or problems of get () and indexOf () operations (in the case of duplication).

(You cannot use a regular int variable instead of AtomicInteger, because variables used from outside a lambda expression must effectively be final variables. Note that AtomicInteger is very fast without controversy, as shown in this example, and does not cause performance problems. But if you’re worried, you can use a non-thread-safe counter.)