Найти N первых элементов, которые удовлетворяют заданному условию: суммы до заданного числа - PullRequest
0 голосов
/ 27 февраля 2019

У меня есть список Pocket экземпляров

List<Pocket> pockets;

, где Pocket класс выглядит следующим образом:

public class Pocket {
    String name;
    Double amount;
}

Пример списка карманов:

[
    {"pocket1", 280},
    {"pocket2", 320},
    {"pocket3", 100},
    {"pocket4", 125},
    {"pocket5", 150},
    {"pocket6", 175}
]

Мне нужно найти n первых карманов, которые вместе могли бы дать N (например, 650) из данного списка карманов.Если в последнем кармане amount больше, чем необходимо, этот карман должен быть разбит на два кармана, а список результатов должен содержать только одну часть, которая вместе с предыдущими n - 1 карманами дает N.

ДляНапример, мне нужно список карманов в порядке, как в списке источников, который дает сумму 650.Обратите внимание, что карман 3-rd был разбит, и в последнем кармане была возвращена только половина amount:

[
    {"pocket1", 280},
    {"pocket2", 320},
    {"pocket3", 50}
]

Как реализовать это с Java Streams?

1 Ответ

0 голосов
/ 27 февраля 2019

Вы можете использовать flatMap и Stream, чтобы сделать это.См. Пример ниже:

import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Stream;

public class Lambda {

    public static void main(String[] args) {
        List<Pocket> pockets = Arrays.asList(
            new Pocket("pocket1", 280D),
            new Pocket("pocket2", 320D),
            new Pocket("pocket3", 100D),
            new Pocket("pocket4", 50D));

        System.out.println("Filtered");
        pockets.stream()
            .flatMap(new SplitFunction(651))
            .forEach(System.out::println);

        System.out.println("Original");
        pockets.forEach(System.out::println);
    }
}


class SplitFunction implements Function<Pocket, Stream<Pocket>> {

private double max;

public SplitFunction(double max) {
    this.max = max;
}

@Override
public Stream<Pocket> apply(Pocket pocket) {
    if (Double.compare(max, pocket.amount) >= 0) {
        max -= pocket.amount;
        return Stream.of(pocket);
    } else if (Double.compare(max, 0.0) > 0) {
        Pocket lastPocket = new Pocket(pocket.name, max);
        max = 0;

        return Stream.of(lastPocket);
    }
    return Stream.empty();
}
}

Над кодом напечатаны:

Filtered
Pocket{name='pocket1', amount=280.0}
Pocket{name='pocket2', amount=320.0}
Pocket{name='pocket3', amount=51.0}
Original
Pocket{name='pocket1', amount=280.0}
Pocket{name='pocket2', amount=320.0}
Pocket{name='pocket3', amount=100.0}
Pocket{name='pocket4', amount=50.0}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...