How to effectively use forEach loop with if conditions inside the loop in Java 8

Viewed 35

I am new to Java8 and want to learn effective ways to use different features introduced. I created this simple program with 2 classes and tried to use forEach loop. But inside the forEach loop I am not sure if I can in anyway use method reference or filter in the below scenario with streams or what I have coded is fine. Any suggestion/help is appreciated. Thank you!

    public class Student {

    private String name;
    private int rollNo;
    private String major;
    
    public Student(String name, int rollNo, String major) {
        this.name = name;
        this.rollNo = rollNo;
        this.major = major;
    }
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getRollNo() {
        return rollNo;
    }
    public void setRollNo(int rollNo) {
        this.rollNo = rollNo;
    }
    public String getMajor() {
        return major;
    }
    public void setMajor(String major) {
        this.major = major;
    }   
}

import java.util.ArrayList;
import java.util.List;

public class Test {
    
    public static void main(String[] args) {
        Student student1 = new Student("Raj", 1, "commerce");
        Student student2 = new Student("Ram", 2, "commerce");
        Student student3 = new Student("Riya", 3, "pcb");
        Student student4 = new Student("Rita", 4, "pcm");
        
        List<Student> studentList_1 = new ArrayList<>();
        studentList_1.add(student1);
        studentList_1.add(student2);
        studentList_1.add(student3);
        studentList_1.add(student4);
        
        List<Student> studentList_2 = new ArrayList<>();
        studentList_2.add(student1);
        studentList_2.add(student2);
        studentList_2.add(student3);
        
        studentList_2.forEach(student -> 
        {
            //this is where I want to check if I can use any of the Java 8 features
            if(studentList_1.contains(student)) {
                boolean isEligibleForDoctor = getEligibility(student.getMajor());
                
                if(isEligibleForDoctor) {
                    System.out.println("Eligible for doctor :: "+student.getName());
                }
            }
        });
    }

    private static boolean getEligibility(String major) {
        if(major.equals("pcb")) {
            return true;
        }else {
            return false;
        }
    }
}
2 Answers

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());
Related