Search code examples
javajava-streamdry

How to create a generic method that works on lists of objects as long as they have the same getter methods


class County{
    private LocalDate date;
    private String county;
    private String district;
    private String region;
    private Integer cases;
// getters and setters and constructor
}
class District{
    private LocalDate date;
    private String district;
    private String region;
    private Integer cases;
// getters and setters and constructor
}

I have a List<County> countyData and List<District> districtData and I would like to use one method to stream both of them. I have successfully been able to stream them by writing two separate methods, but that is not DRY(don't repeat yourself). I would like to write one method that can perform these streams on a list of either objects.

Here is what worked for me but isn't DRY.

List<LocalDate> labels = countyData.stream().map(c -> c.getDate()).collect(Collectors.toList());
List<Integer> totalCases = countyData.stream().map(c -> c.getTotalCases()).collect(Collectors.toList());

and

List<LocalDate> labels = districtData.stream().map(c -> c.getDate()).collect(Collectors.toList());
List<Integer> totalCases = districtData.stream().map(c -> c.getTotalCases()).collect(Collectors.toList());


Here is my attempt at creating one method that handles both

public <T> void genericMethod(List<T> dataList) {

    Collections.reverse(dataList); 

    List<LocalDate> labels = dataList.stream().map(c -> c.getDate()).collect(Collectors.toList());
    List<Integer> totalCases = dataList.stream().map(c -> c.getTotalCases()).collect(Collectors.toList());

}

But I get the following warning: Cannot infer type argument(s) for <R> map(Function<? super T,? extends R>)


Solution

  • Just use polymorphism (this is what Object Oriented Programming is for) : make your County and District classes implement a common interface that contains both methods getDate() and getTotalCases()

    So your method become :

    public void genericMethod(List<YourInterface> dataList)