【问题标题】:I want to add generic type numbers我想添加通用类型编号
【发布时间】:2017-05-15 12:33:10
【问题描述】:

我有一个名为 Employee 的简单类。

public class Employee<T extends Number> {
    private final String id; 
    private final String name;
    private final T salary; //generic type salary

    public Employee(String id,String name,T salary){
        this.id = id;
        this.name = name;
        this.salary = salary;
    }

    public String getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public T getSalary() {
        return salary;
    }

}

在这里使用归约,我可以添加 Double 类型。但我需要添加泛型类型。工资中的值可以是 Double 或 Integer。那么有什么方法可以使用提供任何灵活性,以便我可以添加任何 Sub 类型的 Number。

  public static void main(String[] args) {
        //creates employee list and three employees in it
        List < Employee > employees = new LinkedList < > ();
        employees.add(new Employee("E001", "John", 30000.00));
        employees.add(new Employee("E002", "Mark", 45000.00));
        employees.add(new Employee("E003", "Tony", 55000.00));
        employees.stream().map(Employee::getSalary).reduce(0, (a, b) -> {
        //only able to add double type values, but i need any sub type of number
                return a.doubleValue() + b.doubleValue();
            });
    }



Please help me. 

【问题讨论】:

  • 你得到什么错误?
  • 我没有收到任何错误。我需要知道一种方法,这样我就可以添加整数或双精度数。 employees.stream().map(Employee::getSalary).reduce(0, (a, b) -> { //只能添加双精度类型的值,但我需要任何子类型的数字 return a.doubleValue() + b.doubleValue(); });在这里,我限制了加倍。我需要知道有什么方法可以消除这种限制并使用任何数字类型加法。
  • 没有理智的程序员会使用double 值作为货币值。同样,抽象工资的存储和计算的实际类型的想法是没有意义的。它会无益地引起问题。
  • 通过数字生成永远不会顺利。绝不。为整个程序选择一种数字类型并坚持下去。

标签: java generics java-8 java-stream


【解决方案1】:

我建议您首先在变量声明中添加正确的泛型类型参数:

List<Employee<Double>> employees = new LinkedList<>(); // you need to add "<>"s here
employees.add(new Employee<>("E001", "John", 30000.00));
employees.add(new Employee<>("E002", "Mark", 45000.00));
employees.add(new Employee<>("E003", "Tony", 55000.00));

然后,这将返回一个double,它可以转换为Number,而Number可以转换为intfloatshort等:

Number num = employees.stream().map(Employee::getSalary).reduce(0.0, (a, b) -> {
        return a + b;
});

或者,只是摆脱泛型。不要使用T,而是使用Number 作为薪水类型。

class Employee {
    private final String id;
    private final String name;
    private final Number salary; //generic type salary

    public Employee(String id,String name,Number salary){
        this.id = id;
        this.name = name;
        this.salary = salary;
    }

    public String getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public Number getSalary() {
        return salary;
    }

}

【讨论】:

  • 如果我采用第一种方法,即
  • ' List> employees = new LinkedList(); employees.add(new Employee("E001", "John", 30000.00)); employees.add(new Employee("E002", "Mark", 45000.00)); employees.add(new Employee("E003", "Tony", 55000.00)); Number num = employees.stream().map(Employee::getSalary).reduce(0.0, (a, b) -> { return a + b; });'它给了我错误..二元运算符'+'的错误操作数类型第一类型:数字第二类型:数字
  • 对不起,您指定了,Employee,是的 Number 类没有加法运算。但是我需要知道我可以在 reduce() 方法的累加器部分中使用 if -else 语句,以便我可以检查 a 和 b 的实例类型,基于我可以应用添加到正确的类型。比如 return a.doubleValue() + b.doubleValue();请告诉我在 Java 中是否有任何技巧或方法。
  • @SubhabrataMondal 不,你不会那样做。您不会检查 Number 的具体类型。这就是使用泛型的全部意义所在。您应该只返回一个double,然后将其分配给Number 类型的变量。之后,您可以使用intValue()shortValue() 等将Number 转换为其他类型。
【解决方案2】:

这并不容易......因为编译器无法通过+ 对两个Numbers 进行加法运算。你当然可以在这里使用a cast。当员工的薪水类型为 Double,但 另一个 类型为 Long 时,可能会出现更深层次的问题,在这种情况下,演员表会变得非常讨厌。

如果您可以返回 BigDecimal,一种方法是:

  BigDecimal r = employees.stream().map(Employee::getSalary)
            .map(n -> new BigDecimal(n.toString()))
            .reduce(BigDecimal.ZERO, (left, right) -> {
                return new BigDecimal(left.toString()).add(new BigDecimal(right.toString()));
            });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-31
    • 1970-01-01
    • 2021-09-26
    • 1970-01-01
    • 1970-01-01
    • 2017-02-26
    • 2017-11-03
    • 1970-01-01
    相关资源
    最近更新 更多