Уменьшить, если в потоке Java - PullRequest
0 голосов
/ 03 октября 2018

Как я могу применить операцию уменьшения, только если предикат истинен?

Например:

        Stream.of("foo=X","bar=Y","foo=Z")
        .reduce((arg1, arg2)-> arg1.contains(arg2) ? arg1  : <reduceNothing>)
        .collect(Collectors.toList());

Я хочу избавиться от одного из "foo=...", чтобы иметь взавершить список "foo=X","bar=Y"

Ответы [ 4 ]

0 голосов
/ 03 октября 2018

Вот способ сделать это (без потоков):

Map<String, String> map = new LinkedHashMap<>();

yourListOfArgs.forEach(arg -> map.merge(arg.split("=")[0], arg, (o, n) -> o));

Collection<String> uniqueArgs = map.values();
0 голосов
/ 03 октября 2018

Если есть гибкость в использовании любой другой операции, кроме снижения, тогда ответом может быть следующее:

@Test
public void test(){
    System.out.println(methodContainingFilteringLogic(word -> word.equals("foo=Z"),
            Stream.of("foo=X","bar=Y","foo=Z")));
}

public static List<String> methodContainingFilteringLogic(Predicate<String> predicate, Stream<String> wordsStream) {
    return wordsStream.filter(word -> predicate.negate().test(word))
            .collect(Collectors.toList());
}

В вашем случае будет известно, в какой точке данный поток должен быть отфильтрован.В этот момент можно вызвать methodContainingFilteringLogic.

0 голосов
/ 03 октября 2018

Просто используйте слияние, которое получит первый (в порядке встречи) результат в случае обнаружения дубликата:

Collection<String> result = Stream.of("foo=X", "bar=Y", "foo=Z", "bar=M", "test=12")
            .collect(Collectors.toMap(
                    x -> x.split("=")[0],
                    Function.identity(),
                    (left, right) -> left,
                    LinkedHashMap::new))
            .values();

    System.out.println(result); // [foo=X, bar=Y, test=12]

Я использовал LinkedHashMap на тот случай, если вам нужно сохранить первоначальный порядок, если вам это не нужно, просто используйте:

 Collection<String> result = Stream.of("foo=X", "bar=Y", "foo=Z", "bar=M", "test=12")
            .collect(Collectors.toMap(
                    x -> x.split("=")[0],
                    Function.identity(),
                    (left, right) -> left))
            .values();

  System.out.println(result); // [bar=Y, test=12, foo=X]
0 голосов
/ 03 октября 2018

Попробуйте это:

Stream.of("foo=X","bar=Y","foo=Z")
            .collect(Collectors.toMap(
                    x -> getLeftSide(x),
                    x -> x,
                    (x, y) -> x
            ))
            .values();

Я предполагаю, что у вас есть метод getLeftSide, который возвращает левую часть назначения (преобразовать "foo=bar" в "foo").

...