Java泛型WildCard-如何在此处将Lambda与泛型一起使用?

时间:2019-04-18 11:56:30

标签: java generics lambda java-8

我正在尝试创建一个通用方法。我的DTO是:

public class Master {
    private String string;
    private Date date;

    public String getString() {
        return this.string;
    }

    public Date getDate() {
        return this.date;
    }

    public void setString(String string) {
        this.string = string;
    }

    public void setDate(Date date) {
        this.date = date;
    }
}

扩展Master的My Child类是:

public class Child extends Master {

    private Date newDate;

    public Date getNewDate() {
        return this.newDate;
    }

    public void setNewDate(Date newDate) {
        this.newDate = newDate;
    }
}

现在,我要创建一个通用方法来获取-

public static <T extends Master> Map<String, Map<Date, List<T extends Master>>> getRecalculateMasterMappedByInstrumentIdAndDate(List<T extends Master> masters) {
        return masters.stream().collect(Collectors.groupingBy(Child::getString, Collectors.groupingBy(x -> org.apache.commons.lang3.time.DateUtils.truncate(x.getDate(), Calendar.DAY_OF_MONTH))));
    }

以上内容在编译时给了我一个错误。我该如何为它编写通用方法?

3 个答案:

答案 0 :(得分:1)

删除声明后的边界:

  • 返回类型:Map<String, Map<Date, List<T>>>
  • 参数类型:List<T> masters

您只能将边界与通配符(?)或类型变量的声明一起使用。

答案 1 :(得分:0)

您必须了解类型变量的声明与类型变量的 use 之间的区别。当你写

public static <T extends Master> Map<String, Map<Date, List<T>>>
    getRecalculateMasterMappedByInstrumentIdAndDate(List<T> masters) {
    …
}

<T extends Master>声明类型变量T,其中包括约束T必须是Master的子类型。返回类型T和参数类型Map<String, Map<Date, List<T>>>List<T>的其他出现是使用类型变量T,不需要重复(实际上不允许重复)T的边界。

请注意,您还必须在方法实现中使用Master::getString,因为您不能假定TChild。它可能是Child,但调用者也可以将Master或它的任何子类用于T。幸运的是,无论如何getString已在Master中定义,因此您无需在这里假设Child

答案 2 :(得分:0)

在这里的人们的帮助下,我得以解决。感谢大伙们。我的解决方案:

public static <T extends Master> Map<String, Map<Date, List<T>>> getMastersMappedByInstrumentIdAndDateForRecalculation(List<T> masters) {
        return masters.stream().collect(Collectors.groupingBy(Master::getString, Collectors.groupingBy(x -> org.apache.commons.lang3.time.DateUtils.truncate(x.getDate(), Calendar.DAY_OF_MONTH))));
    }