If you are using Java 8, you can do the following:
Set<String> attributes = Sets.newHashSet("aaa", "bbb", "ccc", "ddd");
Set<String> activeAttributes = Sets.newHashSet("eee", "lll", "ccc", "mmm");
Map<String, Boolean> map = attributes.stream().collect(Collectors.toMap(s -> s, activeAttributes::contains));
System.out.println(map);
For an earlier version of Java and with Guava, you can use Maps.asMap since Guava 14.0:
Map<String, Boolean> map = Maps.asMap(
attributes, Functions.forPredicate(Predicates.in(activeAttributes)));
Note that this returns a live copy (any changes to the set will be reflected on the map). If you want an immutable Map, use Maps.toMap.
This is actually quite simple, despite the convoluted solutions others have offered:
Map<String, List<String>> map = placements.stream()
.collect(groupingBy(Placement::getFutureLinkId, mapping(Placement::getId, toList())));
Using the three-argument toMap is one way to accomplish what you need. (groupingBy appears to be another, but I'm not as familiar with that method.)
For toMap, you need a function that maps your Placement to a key; a function that maps your Placement to a value, which in this case will need to be a set of values; and finally a function that will merge two values together if they have the same key. Something like
Map<String,HashSet<String>> result =
placements.stream()
.collect(Collectors.toMap
(placement -> placement.futureLinkId,
placement -> new HashSet(Collections.singleton(placement.id)),
(s1, s2) -> { HashSet<String> result = new HashSet<>(s1);
result.add(s2);
return result; }));
Note: I haven't tested this. It's possible that this could work without copying s1 if the stream is a sequential stream.
It you don't need a parallel stream you can use the length of the map as an index counter:
collection.stream().forEach(i -> map.put(i, map.size() + 1));
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().