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));
}
}
所以...这是我在 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));
}
}