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.
}
}
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);
}