#java #generics #lambda #java-8
#java #дженерики #лямбда — выражение #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, является:
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))));
}
Вышесказанное выдает мне ошибку во время компиляции. Как я могу написать универсальный метод для того же самого?
Комментарии:
1. Вы не можете использовать
Child
внутри метода, так как компилятор не знает об этом. Компилятор знает толькоMaster
. Либо удалите привязку, либо используйтеMaster
только методы. Здесь абстрактный метод в master также поможет вам сделать это
Ответ №1:
Удалите привязку после объявления:
- Возвращаемый тип:
Map<String, Map<Date, List<T>>>
- Тип параметра:
List<T> masters
.
Вы используете границы только с подстановочными знаками ( ?
) или в объявлении переменных типа.
Ответ №2:
Вы должны понимать разницу между объявлением переменной типа и использованием переменной типа. Когда вы пишете
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
в реализации метода, поскольку вы не можете предположить, что T
это a Child
. Это может быть Child
, но вызывающий объект также может использовать Master
или любой его подкласс для T
. К счастью, getString
это было определено в Master
любом случае, так что вам не нужно Child
здесь предполагать.
Ответ №3:
Я смог решить с помощью людей здесь. Спасибо, ребята. Мое решение:
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))));
}