2017-07-19 59 views
-1

所以...这是我在Stack上的第一篇文章,我也是Java中的新手(进入编程阶段)。我试图制作一个简单的命令行应用程序,根据生成的收入计算员工的利润。已经做到了,但现在我正在学习函数接口和lambdas,我想尝试使用它们。在你的下面你可以找到代码。JAVA - 使用函数接口进行计算

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()方法。这就是我试图使用功能接口的地方。

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

对不起,很长的文章,但想给你我所有的信息。 此外,如果您在我的代码中看到一些错误和不良习惯 - 请让我知道。亲切的问候。

+0

那么,你想让我们用lambda表达式和函数接口来编写这个? –

+3

我不确定你想要问的具体问题是什么。相反,你似乎只是在描述你的项目下一步做什么。 – csmckelvey

+0

是的,这就是我想让你帮助我的。正如你看到我已经尝试过,但效果很差。使用接口和lambda与简单类型如int,String等没有问题。只是不知道如何使用empBonus对象。 @csm_dev - 我想自己做这件事,但不知道为什么。对不起,不太具体。也许我应该问一下...... CalcBonus类应该如何让它工作。 – trybit

回答

0

此接口:

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

没有拉姆达,你必须创建一个子类或匿名类,如果你想通过加倍奖金的实现:

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

lambda的想法是,你可以用lambda表达式内联子类。
你可以这样调用该方法以这样的方式

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

你不需要子类或匿名类的任何时间。

+0

谢谢你所有的解释,并推动我前进。整个代码是为了让我了解接口而编写的 - 仅供练习。我发现的是,我可以在Main类中通过'employee.getEmpBonus(new CalcBonus())'得到正确的输出结果。 – trybit