如何创建适用于对象列表的通用方法,只要它们具有相同的 getter 方法

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
}

我有一个 List<County> countyDataList<District> districtData,我想使用一种方法来流式传输它们。我已经成功地通过编写两个单独的方法来流式传输它们,但这不是 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());

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


这是我尝试创建一种方法来处理两者

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());

}

但我收到以下警告: Cannot infer type argument(s) for <R> map(Function<? super T,? extends R>)

只需使用多态性(这就是面向对象编程的目的):使您的 CountyDistrict 类 实现一个包含两种方法的通用接口 getDate()getTotalCases()

所以你的方法变成了:

public void genericMethod(List<YourInterface> dataList)
class Model{
    protected LocalDate date;
    protected String district;
    protected String region;
    protected Integer cases;
    // getters and setters and constructor
}

class County extends Model{
    private String county;

// getters and setters and constructor
}
class District extends Model{

}

public <Model> void genericMethod(List<Model> 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());

}

这就是我们如何在面向对象编程中使用继承特性。

一个函数可以用作 getList() 中的第二个参数,它可以用于所有属性(在县和区中没有更改/没有继承):

public static <A,B> List<B> getList(List<A> data, Function<A, B> function) {
    return data.stream().map(c -> function.apply(c)).collect(Collectors.toList());
}

public static void main(String[] args) {
    List<County> counties = new ArrayList<>();
    County county1 = new County();
    county1.setDate(LocalDate.now());
    county1.setCases(1);
    County county2 = new County();
    county2.setDate(LocalDate.now());
    county2.setCases(2);
    County county3 = new County();
    county3.setDate(LocalDate.now());
    county3.setCases(1);

    counties.add(county1);
    counties.add(county2);
    counties.add(county3);

    List<District> districts = new ArrayList<>();
    District district1 = new District();
    district1.setDate(LocalDate.now());
    district1.setCases(11);
    District district2 = new District();
    district2.setDate(LocalDate.now());
    district2.setCases(12);
    District district3 = new District();
    district3.setDate(LocalDate.now());
    district3.setCases(13);

    districts.add(district1);
    districts.add(district2);
    districts.add(district3);

    System.out.println(getList(counties, (c -> c.getDate())));
    System.out.println(getList(districts, (d -> d.getDate())));

    System.out.println(getList(counties, (c -> c.getCases())));
    System.out.println(getList(districts, (d -> d.getCases())));
}

[2020-06-09, 2020-06-09, 2020-06-09]
[2020-06-09, 2020-06-09, 2020-06-09]
[1, 2, 1]
[11, 12, 13]