Условия для Списка с Java8 с Потребителем или Фильтром, какой путь лучше - PullRequest
3 голосов
/ 08 июля 2019

Я пробовал это

    List<Integer> numbers = Arrays.asList(1, 1, 0, -1, -1);
    List<Integer> positiveNum2 = new ArrayList<>();
    List<Integer> negativeNum2 = new ArrayList<>();
    List<Integer> zeroNumbers2 = new ArrayList<>();
    List<Integer> positiveNumbers = numbers.stream().filter(number -> number > 0).collect(Collectors.toList());
    List<Integer> negativeNumbers = numbers.stream().filter(number -> number < 0).collect(Collectors.toList());
    List<Integer> zeroNumbers = numbers.stream().filter(number -> number.equals(0)).collect(Collectors.toList());
    positiveNumbers.forEach(System.out::println);
    negativeNumbers.forEach(System.out::println);
    zeroNumbers.forEach(System.out::println);
    System.out.println("*********with Consumer******************");
    Consumer<Integer> determineNumber = number -> {
        if (number > 0) {
            positiveNum2.add(number);
        } else if (number < 0) {
            negativeNum2.add(number);
        } else {
            zeroNumbers2.add(number);
        }

    };
    numbers.forEach(determineNumber);
    positiveNum2.forEach(System.out::println);
    negativeNum2.forEach(System.out::println);
    zeroNumbers2.forEach(System.out::println);

но я не знаю, какой из них лучше, я думаю, что forEach с Потребителем, но Потребитель делает три проверки, поэтому не имеет единой ответственности

Ответы [ 2 ]

1 голос
/ 08 июля 2019

Как правило, я бы предпочел ваше решение на основе Consumer, поскольку оно по меньшей мере инкапсулирует всю операцию в один вызов / поток. Но я думаю, что вы еще не в полной мере используете функциональный подход потоков.

Вы можете использовать простой поток / сбор для достижения этой сортировки:

numbers .stream()
        .collect(Collectors.groupingBy(Math::signum));

приведет к такой карте:

{1.0=[1], 0.0=[0, 0], -1.0=[-1, -2, -1]}

Этот подход позволяет избежать побочных эффектов (т. Е. Не изменять списки вне области видимости потока) и, следовательно, может быть легче извлечен и легко выполняется параллельно.

0 голосов
/ 08 июля 2019

Потребитель берет только одну итерацию, поэтому он более эффективен, и он несет единственную ответственность: деление чисел на три списка на основе их знака.

Для этого случаяЯ, вероятно, использовал бы простой цикл for.

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

import java.util.Arrays;
import java.util.List;
import java.util.Map;

import static java.util.stream.Collectors.groupingBy;

public class Test {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 1, 0, -1, -1);

        Map<Sign, List<Integer>> map = numbers
                .stream()
                .collect(groupingBy(i -> i > 0
                                    ? Sign.POSITIVE
                                    : i < 0 
                                        ? Sign.NEGATIVE
                                        : Sign.ZERO));

        System.out.println(map);
    }
}

enum Sign {POSITIVE, NEGATIVE, ZERO}

Это дает следующий вывод:

{ZERO=[0], POSITIVE=[1, 1], NEGATIVE=[-1, -1]}

Примечание: Если вы хотите пиковой производительности для будущих поисков в вашемкарту, вы можете использовать вместо EnumMap.Взгляните на этот ответ чтобы узнать как.

...