Reputation: 808
I have a Map<String, Boolean>
with the following entries:
{‘John’:false,
'Mike':false,
'Tom':true,
'Harry':false,
'Bob': false}
I need to find the first entry and its index which has the value true. Here I should get Tom and 3 (say, index starts with 1).
I can iterate the map and get these values:
int itr=0;
for(Iterator<Map.Entry<String, Boolean>> entries = map.entrySet().iterator; entries.hasNext(); ) {
itr++;
Map.Entry<String, Boolean> entry = entries.next();
if(entry.getValue()) {
name = entry.getKey();
index = itr;
}
}
However, I am looking at a lambda expression for the same.
Upvotes: 1
Views: 1568
Reputation: 100199
I think it's not possible to fulfill all the conditions below:
If you ok with violating #1, check the @Eugene's answer. If you ok with violating #2, then your code in the question is nice. If you ok with violating #3, you can do something like this:
AtomicInteger idx = new AtomicInteger();
String name = map.entrySet().stream()
.peek(e -> idx.incrementAndGet())
.filter(Map.Entry::getValue)
.map(Map.Entry::getKey)
.findFirst().orElse(null);
int itr = idx.get();
If you're ok to violate #4, you may consider using my free StreamEx library:
Map.Entry<String, Integer> entry = StreamEx.of(map.entrySet()) // (name, bool)
.zipWith(IntStreamEx.ints().boxed()) // ((name, bool), index)
.filterKeys(Map.Entry::getValue) // filter by bool
.mapKeys(Map.Entry::getKey) // (name, index)
.findFirst()
.orElse(null);
if(entry != null) {
String name = entry.getKey();
int itr = entry.getValue();
}
Upvotes: 3
Reputation: 120848
Well if you can guarantee that Map is actually a LinkedHashMap (so that it preserves insertion order), you can do something like this:
List<Map.Entry<String, Boolean>> l = map.entrySet().stream().collect(Collectors.toList());
IntStream.range(0, l.size())
.mapToObj(i -> new AbstractMap.SimpleEntry<>(i, l.get(i)))
.filter(e -> e.getValue().getValue())
.map(e -> new AbstractMap.SimpleEntry<>(e.getValue().getKey(), e.getKey()))
.findFirst();
Upvotes: 3