Filter by class without using stream when reading an array of objects with Java lambda expressions 8

2

I'm testing the Java 8 Lambda expressions.

In my code I create a list of objects that can be of type Person or type Employee .

The class Employee extends from Person and I want, using a lambda expression to display the information using the showData method only of the objects in the list that are of type Employee .

That's how it works for me:

    lstPersons.stream().filter(item -> item instanceof Employee)
        .forEach(theEmployee -> theEmployee.showData()); 
    }

But here use stream and use map .

Since I can read all the objects like this:

    lstPersons.forEach(item -> item.showData());

Is there no simpler way to apply the filter, without having to use stream and map ?

Here you can see a DEMO of the code I'm testing. p>     

asked by A. Cedano 07.07.2018 в 06:48
source

1 answer

0

I recommend that you follow the principles of object-oriented programming , using property encapsulation, and separating classes into different files , from the following way:

Person Class:

public class Person {

    private String firstName;
    private String lastName;
    private int idNumber;

    public Person(String firstName, String lastName, int idNumber) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.idNumber = idNumber;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public int getIdNumber() {
        return idNumber;
    }

    public void setIdNumber(int idNumber) {
        this.idNumber = idNumber;
    }

    public void showData() {
        String s = String.format("Nombre: %s%nApellido :%s%nID: %s%n%n", firstName, lastName, idNumber);
        System.out.print(s);
    }
}

Employee Class:

public class Employee extends Person {

    private String areaName;
    private double amountSalary;

    public Employee(String firstName, String lastName, int idNumber, String areaName, Double amountSalary) {
        super(firstName, lastName, idNumber);
        this.areaName = areaName;
        this.amountSalary = amountSalary;

    }

    public String getAreaName() {
        return areaName;
    }

    public void setAreaName(String areaName) {
        this.areaName = areaName;
    }

    public double getAmountSalary() {
        return amountSalary;
    }

    public void setAmountSalary(double amountSalary) {
        this.amountSalary = amountSalary;
    }

    @Override
    public void showData() {
        String s = String.format("Nombre: %s%nApellido :%s%nID: %s%nÁrea :%s%nSalario :%.2f%n%n", getFirstName(),
                getLastName(), getIdNumber(), areaName, amountSalary);
        System.out.print(s);

    }
}

Rextester Class:

Here, we can use Predicado , which is a functional interface that define a Boolean condition (true or false), for example, that the class person has a certain id, that the elements are of the class employed or person only, and any business rules you need.

Now, we can encapsulate a method that when receiving a list of people, apply a certain tester (predicate) to print the list:

public static void printPersonWithPredicate(List<Person> persons, Predicate<Person> tester) {
        for (Person p : persons) {
            if (tester.test(p)) { //Si pasa el test
                p.showData(); //imprime los datos
            }
        }
    }

Finally we can use it to print according to the searched condition:

printPersonWithPredicate(lstPersons, p -> p.getClass() == Employee.class);

I will leave you the complete class with which I will test so that you do not have problems, I also tried printing only People:

import java.util.*;
import java.util.function.Predicate;

public class Rextester {

    public static void main(String args[]) {

        final List<Person> lstPersons = new ArrayList<>();
        lstPersons.add(new Employee("Empleado1", "Ap1", 123456, "Informática", 2000.50));
        lstPersons.add(new Person("Persona1", "Apellido1", 1));
        lstPersons.add(new Employee("Empleado2", "Ap2", 123457, "Contabilidad", 1900.00));
        lstPersons.add(new Person("Persona2", "Apellido2", 2));
        lstPersons.add(new Person("Persona3", "Apellido3", 3));

        /* Leer todas las Personas */
        System.out.printf("%s%n%n", "TODAS LAS PERSONAS:");
        lstPersons.forEach(item -> item.showData());

        /* Leer los Empleados */
        System.out.printf("%n%s%n%n", "SOLAMENTE LOS EMPLEADOS:");

        printPersonWithPredicate(lstPersons, p -> p.getClass() == Employee.class);

        /* Leer las personas */
        System.out.printf("%n%s%n%n", "SOLAMENTE LAS PERSONAS:");

        printPersonWithPredicate(lstPersons, p -> p.getClass() == Person.class);

    }

    public static void printPersonWithPredicate(List<Person> persons, Predicate<Person> tester) {
        for (Person p : persons) {
            if (tester.test(p)) {
                p.showData();
            }
        }
    }

}

Output:

To finish, the output would be the following:

TODAS LAS PERSONAS:

Nombre: Empleado1
Apellido :Ap1
ID: 123456
Área :Informática
Salario :2000.50

Nombre: Persona1
Apellido :Apellido1
ID: 1

Nombre: Empleado2
Apellido :Ap2
ID: 123457
Área :Contabilidad
Salario :1900.00

Nombre: Persona2
Apellido :Apellido2
ID: 2

Nombre: Persona3
Apellido :Apellido3
ID: 3


SOLAMENTE LOS EMPLEADOS:

Nombre: Empleado1
Apellido :Ap1
ID: 123456
Área :Informática
Salario :2000.50

Nombre: Empleado2
Apellido :Ap2
ID: 123457
Área :Contabilidad
Salario :1900.00


SOLAMENTE LAS PERSONAS:

Nombre: Persona1
Apellido :Apellido1
ID: 1

Nombre: Persona2
Apellido :Apellido2
ID: 2

Nombre: Persona3
Apellido :Apellido3
ID: 3
    
answered by 10.07.2018 в 09:02