接受通用列表作为参数,并根据其类型使用它

use*_*295 5 java generics spring list

我正在为公司开发一个网站,并且使用Spring作为后端。现在有一种情况,我需要两次使用一种Utils方法,但是要使用不同的DAO。

为了避免代码重复,我想知道如何使用Java泛型来使该方法可用于两种情况。该方法仅计算两个DAO共有的字段之一。

使用方法:

SeverityCount calculateSeveritiesCount(List<?> events){

        if(null == events){
            return new SeverityCount();
        }

        if(events.get(1) instanceof EventDAO){
            events = (List<EventDAO>)events;
        }
        else if (events.get(1) instanceof EventsByAreaDAO) {
            events = (List<EventsByAreaDAO>)events;
        }

        Map<String, Long> severityCountMap = events.stream().collect(
            Collectors.groupingBy(
                EventDAO::getSeverity,  //It should be EventDAO or EventsByAreaDAO. both has severity field.
                Collectors.counting())
        );

        return mapper.convertValue(severityCountMap, SeverityCount.class);
    }
Run Code Online (Sandbox Code Playgroud)

活动DAO:

@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "events")
public class EventDAO {
    @Id @Column(name = "uid")
    private String uID;

    private String date;

    private String severity;

}
Run Code Online (Sandbox Code Playgroud)

区域DAO:

@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "events")
public class EventsByRegionDAO {

     @Id @Column(name = "uid")
    private String uID;

    private String date;

    private String type;

    private String severity;

    private String area;

    private String server;
}
Run Code Online (Sandbox Code Playgroud)

这就是我从服务中调用它的方式:

SeverityCount severitiesCount = Utils.calculateSeveritiesCount(eventsList);  //EventsList could be list of EventDAO or EventsByAreaDAO
Run Code Online (Sandbox Code Playgroud)

Mar*_*cak 5

您可以将方法更改为

SeverityCount calculateSeveritiesCount(List<? extends SeverityCalculable> events)
Run Code Online (Sandbox Code Playgroud)

哪里 SeverityCalculable

interface SeverityCalculable {
    String getSeverity(); // implemente getter in all subclasses
}
Run Code Online (Sandbox Code Playgroud)

让您所有相关的类都实现此接口。

public class EventDAO implements SeverityCalculable  {

    // ...

    @Override
    public String getSeverity() {
        return this.severity;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,在您的方法中,删除强制类型转换,它应该变成这样:

 SeverityCount calculateSeveritiesCount(List<? extends SeverityCalculable> events) {

    if(null == events){
        return new SeverityCount();
    }

    Map<String, Long> severityCountMap = events.stream().collect(
        Collectors.groupingBy(
            SeverityCalculable::getSeverity,
            Collectors.counting()
        )
    );

    return mapper.convertValue(severityCountMap, SeverityCount.class);
}
Run Code Online (Sandbox Code Playgroud)