I am trying to create a generic method. My dtos are:
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;
}
}
My Child class which extends Master is:
public class Child extends Master {
private Date newDate;
public Date getNewDate() {
return this.newDate;
}
public void setNewDate(Date newDate) {
this.newDate = newDate;
}
}
Now, what I want to do is create a generic method to get -
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))));
}
The above is giving me an error during compile time. How can I write a generic method for the same?
Remove the bound after the declaration:
Map<String, Map<Date, List<T>>>
List<T> masters
. You only use bounds with wildcards ( ?
), or in the declaration of the type variables.
You have to understand the difference between the declaration of a type variable and the use of the type variable. When you write
public static <T extends Master> Map<String, Map<Date, List<T>>>
getRecalculateMasterMappedByInstrumentIdAndDate(List<T> masters) {
…
}
The <T extends Master>
declares the type variable T
including the constraint that T
must be a subtype of Master
. The other occurrences of T
within the return type Map<String, Map<Date, List<T>>>
and the parameter type List<T>
are using the type variable T
and don't need to repeat (and are in fact not allowed to repeat) the bounds of T
.
Note that you also have to use Master::getString
in the method implementation as you can't assume that T
is a Child
. It may be Child
, but the caller can also use Master
or any subclass of it for T
. Thankfully, getString
has been defined in Master
anyway, so you don't need to assume Child
here.
I was able to solve with the help of folks here. Thank you, guys. My solution:
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))));
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.