Implementing different predicates for different types of employees

Devin :

I'm new to using predicates and not sure if I'm understanding it properly. I have an abstract employee class in which hourly and salary employee's are created separately. My issue relies in my EmployeePredicate.java class where I am unsure how to check whether it is an hourly employee and to return true or false.

I need to create a different predicate for all of the following conditions:

All employees, Hourly Only, Salary Only and Fulltime Only.

So far I am only trying to get the "Hourly Only" Predicate to work properly first and think I could figure out the rest after that. I am unsure what to put after the 'p' to check which type of employee it is. What I have currently is:

public static Predicate<Employee> isHourlyEmployee() {
        return p -> p.
    }

I also have the statement double avgSalary = calculateAveragePay(employees, null); and am unsure what to replace null with as it should be a predicate based off my calculateAveragePay function above in main.

Main.java

package homework04;

import java.util.function.Predicate;

public class Main {

public static double calculateAveragePay(Employee[] employees, Predicate<Employee> pred) {
    double sum = 0.0;
    int count = 0;
    for(Employee e : employees) {
        if(!pred.test(e)) {             
            continue;
        }
        sum += e.calculatePay();
        count++;
    }
    return sum / count;
}

public static void main(String[] args) {
    //The list of employees to calculate.
    Employee[] employees = {
        new HourlyEmployee("John Smith", 80, 18.00),
        new HourlyEmployee("Jane Doe", 77, 20.00),
        new SalaryEmployee("Bob Miller", 85, 40000.00),
        new HourlyEmployee("Alice Davis", 40, 12.50),
        new SalaryEmployee("Frank Frink", 70, 35000.00),
        new HourlyEmployee("Chris Williams", 95, 25.00)
    };

    //The average pay for both types of employee.
    double avgSalary = calculateAveragePay(employees, null);
    double avgHourly = calculateAveragePay(employees, null);

    //The bonus to be added to employee pay.
    //double bonus = Math.abs(avgSalary - avgHourly);

    //Print the average pay
    System.out.println("===== Average Pay =====");

}

}

Employee.java

package homework04;

import java.util.function.Predicate;

abstract class Employee {

    private String name;
    private int hoursWorked;

    public Employee(String name, int hoursWorked) {
        this.name = name;
        this.hoursWorked = hoursWorked;
    }

    public int getHoursWorked() {
        return hoursWorked;
    }

    public String getName() {
        return name;
    }

    public abstract double calculatePay();

}

HourlyEmployee.java

package homework04;

public class HourlyEmployee extends Employee {

    private double hourlyPay;

    public HourlyEmployee(String name, int hoursWorked, double hourlyPay) {
        super(name, hoursWorked);
        this.hourlyPay = hourlyPay;
    }

    @Override
    public double calculatePay() {
        return getHoursWorked() * hourlyPay;
    }

}

SalaryEmployee.java

package homework04;

public class SalaryEmployee extends Employee {

    private static final int NUM_PAY_PERIODS = 26;

    private double salary;

    public SalaryEmployee(String name, int hoursWorked, double salary) {
        super(name, hoursWorked);
        this.salary = salary;
    }

    @Override
    public double calculatePay() {
        return salary / NUM_PAY_PERIODS;
    }

}

EmployeePredicate.java

package homework04;

import java.util.function.Predicate;

public class EmployeePredicate {

    public static Predicate<Employee> isHourlyEmployee() {
        return p -> p.
    }

}
Ousmane D. :

You're looking for:

 return p -> p instanceof HourlyEmployee;

but I wouldn't suggest the approach of creating a predicate for each Employee type in your EmployeePredicate factory class, instead just pass in the behavior when calling the calculateAveragePay method i.e.

double avgSalary = calculateAveragePay(employees, p -> p instanceof SalaryEmployee);
double avgHourly = calculateAveragePay(employees, p -> p instanceof HourlyEmployee);

Nevertheless, if you want to proceed with your factory class of Predicate methods because you feel it provides better readability then you can do:

public class EmployeePredicate {
    public static Predicate<Employee> isHourlyEmployee() {
        return p -> p instanceof HourlyEmployee;
    }
}

Then the method calls to calculateAveragePay become:

double avgSalary = calculateAveragePay(employees, EmployeePredicate.isSalaryEmployee()); // create the isSalaryEmployee method
double avgHourly = calculateAveragePay(employees, EmployeePredicate.isHourlyEmployee());

As an aside, you could use the stream API to perform the calculateAveragePay making it more readable.

public static double calculateAveragePay(Employee[] employees, Predicate<Employee> pred) {
    return Arrays.stream(employees)
                 .filter(pred)
                 .mapToDouble(e -> e.calculatePay()) 
                 .average().orElse(0);
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=131894&siteId=1