使用带有Consumer或Filter的Java8的列表的条件,哪种方法更好

时间:2019-07-08 03:41:42

标签: java foreach java-8 java-stream consumer

我已经尝试过了

    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 个答案:

答案 0 :(得分:1)

我通常更喜欢您的基于Consumer的解决方案,因为它至少将整个操作封装在一个调用/流中。但是我认为您尚未充分利用流的功能方法。

您可以使用简单的流/收集来实现这种排序:

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

将产生这样的地图:

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

这种方法避免了副作用(即不会在流范围之外修改列表),因此可以更轻松地提取并且可以并行运行。

答案 1 :(得分:0)

使用者只需要进行一次迭代,因此效率更高,并且 负有单一责任:根据符号将数字划分为三个列表。

在这种情况下,我可能会使用一个简单的MultiPolygon循环。

如果您真的想对工程进行过度设计,可以定义一个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]} 。看一下this answer,了解操作方法。