JAVA - 使用函数式接口进行计算

JAVA - Use functional interface for calculations

所以...这是我在 Stack 上的第一个 post,而且我也是 Java 的新手(完全不了解编程)。我正在尝试制作一个简单的命令行应用程序,它将根据产生的收入计算员工的利润。已经这样做了,但由于我现在正在学习功能接口和 lambda,我想尝试使用它们。您可以在下方找到代码。

package BalanceCounter;

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

public class Main {
public static void main(String[] args) {

    Scanner input = new Scanner(System.in);
    System.out.print("Number of employees: ");
    int empCounter = input.nextInt();
    System.out.println();

    List<Employee> employees = new ArrayList<>(empCounter);
    for (int i = 0; i < empCounter; i++) {
        employees.add(new Employee());
    }

    for (Employee employee : employees) {
        System.out.println("Employee: " + employee.getEmpName()
                + "\nBase salary: " + employee.getEmpBaseSalary()
                + "\nProfit from income: " + employee.getEmpBonus()
                + "\n");
    }
}
}

这是在评论块中使用 getEmpBonus() 方法的员工 class。这就是我尝试使用功能接口的地方。

package BalanceCounter;

import java.util.Scanner;

class Employee {
private String empName;
private double empBaseSalary;
private double empIncome;
private double empBonus;


Employee() {
    Scanner input = new Scanner(System.in);

    System.out.print("Employees name: ");
    setEmpName(input.nextLine());

    System.out.print("Type basic salary: ");
    setEmpSalary(input.nextDouble());

    System.out.print("Generated income: ");
    setEmpIncome(input.nextDouble());
    setEmpBonus();

    System.out.println();
}

/*
 * Here are all the setters
 */

private void setEmpName(String empName) {
    this.empName = empName;
}

private void setEmpSalary(double empBaseSalary) {
    this.empBaseSalary = empBaseSalary;
}

private void setEmpIncome(double empIncome) {
    this.empIncome = empIncome;
}

private void setEmpBonus() {
    if (getEmpIncome() <= 10000)
        empBonus = (getEmpIncome() * 3) / 100;
    else if (getEmpIncome() > 10000 && getEmpIncome() <= 20000)
        empBonus = (getEmpIncome() * 2) / 100;
    else empBonus = (getEmpIncome() * 1) / 100;
}


/*
 * Time for the getters
 */

String getEmpName() {
    return empName;
}

double getEmpBaseSalary() {
    return empBaseSalary;
}

private double getEmpIncome() {
    return empIncome;
}

double getEmpBonus() {
    return empBonus;
}

/*
 * double getEmpBonus(Calculation calculation) {
 * return empBonus = calculation.calculate(this.empBonus);
 * }
 */

}

最后是计算界面

package BalanceCounter;


public interface Calculation {
    double calculate(double arg);
}

class CalcBonus implements Calculation{
    public double calculate(double empBonus) {
        return empBonus;
    }
}

抱歉拖了这么久 post 但我想告诉你我所有的信息。 另外,如果您在我的代码中看到一些错误和坏习惯 - 请告诉我。亲切的问候。

这个界面:

public interface Calculation {
    double calculate(double arg);
}

DoubleUnaryOperator有相同的合同:

@FunctionalInterface
public interface DoubleUnaryOperator {
    double applyAsDouble(double operand);
   ...
}

所以你真的不需要为此引入新的界面。
你可以使用内置的。
但是如果你真的想强调方法的名称和/或参数。

一般情况下,在创建内置函数式接口之前先看看是否符合你的要求。

假设现在您取消注释您的方法并且您想使用此方法:

  double getEmpBonus(DoubleUnaryOperator calculation) {
     return empBonus = calculation.applyAsDouble(this.empBonus);
  }

如果没有 lambda,你必须创建一个 subclass 或匿名 class 如果你想通过一个双倍奖励的实现:

class DoubleBonus implements DoubleUnaryOperator {
    public double applyAsDouble(double operand) {
        return operand * 2;
    }
}

lambda 的想法是您可以将 subclass 与 lambda 表达式内联。
您可以这样调用该方法:

double doubledBonus = getEmpBonus(empBonus->empBonus*2);

您不再需要子class或匿名class。

package training;
public class Calculator {
    interface IntegerMath {
        int operation(int a, int b);
    }
    interface RealMath {
        double operation(double a, double b);
    }
    public int operateBinary(int a, int b, IntegerMath op) {
        return op.operation(a, b);
    }
    public double operateBinary(int a, int b, RealMath op) {
        return op.operation(a, b);
    }
    public static void main(String... args) {
        Calculator cal = new Calculator();
        IntegerMath addition = (a, b) -> a + b;
        IntegerMath subtraction = (a, b) -> a - b;
        IntegerMath multiplication = (a, b) -> a * b;
        RealMath division = (a, b) -> a / b;
                System.out.println("Add: 40 + 22 = " +
                cal.operateBinary(40, 22, addition));
        System.out.println("Sub: 120 - 80 = " +
                cal.operateBinary(120, 80, subtraction));
        System.out.println("Mul: 12 * 12 = " +
                cal.operateBinary(12, 12, multiplication));
        System.out.println("Div: 478 / 12 = " +
                cal.operateBinary(478, 12, division));
    }
}