java8 удалить объекты из списка основных условий объекта - PullRequest
0 голосов
/ 22 января 2019

Допустим, у меня есть модель

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 должен помочь мне оставить только людей, у которых *Только 1015 * или 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?

Ответы [ 2 ]

0 голосов
/ 22 января 2019

Сначала необходимо объединить экземпляров, которые имеют одинаковые 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;
    }
}

Затем вы можете использовать вышеописанный метод, чтобы уменьшить ваш 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) и объединяет их при любом столкновении, суммируя их поля came и gone.

Теперь мы готовы удалить Travellers экземпляров из значений карты, которые не завершили поездку туда и обратно:

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

Чтобы удалить такие экземпляры, мы используем метод Collection.removeIf. Если вы в порядке с Collection<Travellers>, все готово. Если вам нужен List<Travellers>, просто выполните:

List<Travellers> result = new ArrayList<>(grouped.values());
0 голосов
/ 22 января 2019
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());
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...