Here's an approach:
List<String> list = Arrays.asList("a", "b", "c");
Map<String, Integer> map =
IntStream.range(0, list.size())
.boxed()
.collect(toMap(i -> list.get(i), i -> i));
Not necessarily a one-liner or shorter than the straightforward loop, but it does work using a parallel stream if you change toMap
to toConcurrentMap
.
Also note, this assumes that you have a random-access list, not a general Collection
. If you have a Collection
that you otherwise can make no assumptions about, there's not much you can do other than to iterate over it sequentially and increment a counter.
UPDATE
The OP has clarified that the input is a Collection
and not a List
so the above doesn't apply. It seems that we can assume very little about the input Collection
. The OP has specified iteration order. With a sequential iterator, the elements will come out in some order although no guarantees can be made about it. It might change from run to run, or even from one iteration to the next (though this would be unusual in practice -- unless the underlying collection is modified).
If the exact iteration order needs to be preserved, I don't believe there's a way to preserve it into the result Map
without iterating the input Collection
sequentially.
If, however, the exact iteration order isn't important, and the requirement is that the output Map
have unique values for each input element, then it would be possible to do something like this in parallel:
Collection<String> col = apiCall();
Iterator<String> iter = col.iterator();
Map<String, Integer> map =
IntStream.range(0, col.size())
.parallel()
.boxed()
.collect(toConcurrentMap(i -> { synchronized (iter) { return iter.next(); }},
i -> i));
This is now far from a one-liner. It's also not clear to me how useful it is. :-) But it does demonstrate that it's possible to do something like this in parallel. Note that we've had to synchronize access to the input collection's iterator since it will be called from multiple threads. Also note that this is an unusual use of the iterator, since we never call hasNext
and we assume that it is safe to call next
exactly the number of times returned by the input collection's size()
.