java8从对象列表基本条件中删除对象

时间:2019-01-22 06:56:23

标签: java collections java-8

让我说我有模特

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的流式传输/过滤中实现?

2 个答案:

答案 0 :(得分:2)

您首先需要合并个具有相同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;
    }
}

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

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

此{em>将Travellers个实例按(travellerId, routeId)对分组,并在发生任何冲突时合并它们,将它们的camegone字段相加。 / p>

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

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

要删除此类实例,我们使用Collection.removeIf方法。如果您对Collection<Travellers>感到满意,那么您就完成了。如果您需要List<Travellers>,只需执行以下操作:

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

答案 1 :(得分:1)

private static List<Travellers> removeRoundTrips(List<Travellers> travellers) {
    return travellers.stream().collect(Collectors.groupingBy(Travellers::getRouteId)).values().stream()
                     .filter(v -> v.stream().anyMatch(value -> value.getCame() > 0) ^ v.stream().anyMatch(value -> value.getGone() > 0))
                     .map(values -> values.iterator().next())
                     .collect(Collectors.toList());
}