让我说我有模特
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
应该帮助我,只留下那些拥有came
或gone
的人。
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的流式传输/过滤中实现?
答案 0 :(得分:2)
您首先需要合并个具有相同travellerId
和routeId
的实例,将它们的came
和gone
属性相加。为此,您可以在某些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)
对分组,并在发生任何冲突时合并它们,将它们的came
和gone
字段相加。 / 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());
}