No.
You could use a while loop instead.
Iterator iterator = list.iterator();
while(iterator.hasNext()) {
...
}
Answer from NimChimpsky on Stack OverflowNo.
You could use a while loop instead.
Iterator iterator = list.iterator();
while(iterator.hasNext()) {
...
}
No, there is nothing like that. The "enhanced for loop" is a completely separate construct that does nothing except lopp through the iterator returned by its Iterable parameter.
What you can do is this:
for(Foo foo : foos)
{
//Do something
if(!condition){
break;
}
}
You can make something like this instead.
- Filter the student list for the condition you need.
- Then using the forEach to produce a side effect (printing the eligibles names in this example).
Here it is more readable and without the nesting if:
List<Student> eligables =
studentList_2
.stream()
.filter(s -> studentList_1.contains(s) && getEligibility(s.getMajor()))
.collect(Collectors.toList());
eligables.forEach(s -> System.out.println("Eligible for doctor :: " + s.getName()));
Firstly, you need to create a stream using Collection.stream() method.
To retain only students contained in the second list and to check the major property of a student, You can use filter() operation.
Note: that you need to implement equals/hashCode contract in order to compare Student objects based on their properties.
And to make contains() check more performant, you can dump the student from the second list into a HashSet.
That's how it might be implemented:
List<Student> studentList1 = // initializing list1
List<Student> studentList2 = // initializing list2
Set<Student> toCheck = new HashSet<>(studentList2);
studentList2.stream()
.filter(toCheck::contains)
.filter(student -> student.getMajor().equals("pcb"))
.map(Student::getName)
.forEach(name -> System.out.println("Eligible for doctor :: " + name));
You might want to store these name, that's how it can be done
List<String> isEligibleForDoctorNames = studentList2.stream()
.filter(toCheck::contains)
.filter(student -> student.getMajor().equals("pcb"))
.map(Student::getName)
.collect(Collectors.toList());
Just put the condition into the lambda itself, e.g.
animalMap.entrySet().stream()
.forEach(
pair -> {
if (pair.getValue() != null) {
myMap.put(pair.getKey(), pair.getValue());
} else {
myList.add(pair.getKey());
}
}
);
This can be simplified and made more readable using Map.forEach, as suggested by Jorn Vernee:
animalMap.forEach(
(key, value) -> {
if (value != null) {
myMap.put(key, value);
} else {
myList.add(key);
}
}
);
Of course, these solutions assume that both collections (myMap and myList) are declared and initialized prior to the above pieces of code.
In most cases, when you find yourself using forEach on a Stream, you should rethink whether you are using the right tool for your job or whether you are using it the right way.
Generally, you should look for an appropriate terminal operation doing what you want to achieve or for an appropriate Collector. Now, there are Collectors for producing Maps and Lists, but no out of-the-box collector for combining two different collectors, based on a predicate.
Now, this answer contains a collector for combining two collectors. Using this collector, you can achieve the task as
Pair<Map<KeyType, Animal>, List<KeyType>> pair = animalMap.entrySet().stream()
.collect(conditional(entry -> entry.getValue() != null,
Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue),
Collectors.mapping(Map.Entry::getKey, Collectors.toList()) ));
Map<KeyType,Animal> myMap = pair.a;
List<KeyType> myList = pair.b;
But maybe, you can solve this specific task in a simpler way. One of you results matches the input type; it’s the same map just stripped off the entries which map to null. If your original map is mutable and you don’t need it afterwards, you can just collect the list and remove these keys from the original map as they are mutually exclusive:
List<KeyType> myList=animalMap.entrySet().stream()
.filter(pair -> pair.getValue() == null)
.map(Map.Entry::getKey)
.collect(Collectors.toList());
animalMap.keySet().removeAll(myList);
Note that you can remove mappings to null even without having the list of the other keys:
animalMap.values().removeIf(Objects::isNull);
or
animalMap.values().removeAll(Collections.singleton(null));
If you can’t (or don’t want to) modify the original map, there is still a solution without a custom collector. As hinted in Alexis C.’s answer, partitioningBy is going into the right direction, but you may simplify it:
Map<Boolean,Map<KeyType,Animal>> tmp = animalMap.entrySet().stream()
.collect(Collectors.partitioningBy(pair -> pair.getValue() != null,
Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)));
Map<KeyType,Animal> myMap = tmp.get(true);
List<KeyType> myList = new ArrayList<>(tmp.get(false).keySet());
The bottom line is, don’t forget about ordinary Collection operations, you don’t have to do everything with the new Stream API.