可以说我有一个模特

Class Travellers{
    private int travellerId;
    private String routeId
    private int came;
    private int gone;
}


这样旅行者可以去(归因came)一个route然后回来(归因
 gone)。我正试图删除已完成往返旅行的所有旅行者。示例条目:

id      routeId     came        gone
1       R1          1           0
1       R1          0           1
2       R2          0           1


所以R1应该被过滤掉,只有R2被保留

基本上,removeRoundTrips应该可以帮助我仅保留拥有camegone的人员。

private List<Travellers> removeRoundTrips(List<Travellers> travellers){
    // right now its a classic 'for' loop here
    // expectation of something like

    travellers.stream()
                .filter( traveller -> someFunctionWhichFilters)
                .collect(Collectors.toList())

}


有没有一种方法可以在java8中的流式传输/过滤中实现?

最佳答案

首先,您需要合并具有相同travellerIdrouteId的实例,并对它们的camegone属性求和。为此,您可以在某些TravellersUtility帮助器类中使用以下实用程序方法:

public final class TravellersUtility {

    private TravellersUtility() { }

    public static Travellers merge(Travellers left, Travellers right) {
        Travellers t = new Travellers();
        t.setRouteId(left.getRouteId());
        t.setTravellerId(left.getTravellerId());
        t.setCame(left.getCame() + right.getCame());
        t.setGone(left.getGone() + right.getGone());
        return t;
    }
}


然后,您可以使用上述方法通过使用List<Travellers>来减小Collectors.toMap

Map<List<Object>, Travellers> grouped = travellers.stream()
          .collect(Collectors.toMap(
                              t -> Arrays.asList(t.getTravellerId(), t.getRouteId()),
                              Function.identity(),
                              TravellersUtility::merge));


这会将Travellers实例按(travellerId, routeId)对进行分组,并在发生任何冲突时合并它们,将它们的camegone字段相加。

现在,我们准备从尚未完成往返的地图值中删除Travellers实例:

grouped.values().removeIf(t -> t.getCame() > 0 && t.getGone() > 0);


要删除此类实例,我们使用Collection.removeIf方法。如果您对Collection<Travellers>没问题,就可以了。如果您需要List<Travellers>,只需执行以下操作:

List<Travellers> result = new ArrayList<>(grouped.values());

07-26 03:10