我想添加泛型类型号

时间:2017-05-15 12:33:10

标签: java generics java-8 java-stream

我有一个名为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类型的数字。

  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. 

2 个答案:

答案 0 :(得分:4)

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

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,可转换为NumberNumber可转换为intfloat,{{1}等等:

short

或者,只是摆脱泛型。不要使用Number num = employees.stream().map(Employee::getSalary).reduce(0.0, (a, b) -> { return a + b; }); ,而只需使用T作为薪水类型。

Number

答案 1 :(得分:0)

由于编译器无法通过+在两个Number上进行添加,因此不容易解决这个问题。你当然可以在这里使用a cast。当Employee的工资类型为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()));
            });