performance - 使用 Java 8 查找连续子列表的负和

标签 performance list lambda functional-programming java-8

我正在尝试优化以下代码:

private final static class SubarrayProcessorNegativeSumStrategy 
    implements SubarrayProcessorStrategy {
    @Override public Integer apply(Integer[] array) {
        final List<Integer> numbers = Arrays.asList(array);
        return (int) IntStream.range(0, numbers.size())
            .map(index -> findNegativeSums(numbers, index)).sum();
    } 
    private Integer findNegativeSums(final List<Integer> numbers, 
                                     final Integer startIndex) {
    final Integer numbersSize = numbers.size();
    if (startIndex < numbersSize) {
        return (int) IntStream.range(startIndex, numbers.size())
        .map(newIndex -> numbers.subList(startIndex, newIndex + 1)
        .stream().mapToInt(x -> x).sum())
        .filter(sum -> sum < 0).count();
    } else {
        return 0;
    }
}

我想避免为原始列表的每个元素从 startIndex 迭代到 newIndex + 1

numbers.subList(startIndex, newIndex + 1).stream().mapToInt(x -> x).sum()

您对我如何实现这一点有什么建议吗?或者您是否可以提供任何改进以获得相同的结果?

谢谢

问候,

最佳答案

如果你想通过Stream API来实现,就没有必要走List API的弯路了。此外,如果您执行单个 flatMap 流操作,则 «元素计数总和» 是所有元素的总数:

private final static class SubarrayProcessorNegativeSumStrategy
    implements SubarrayProcessorStrategy {
    @Override public Integer apply(Integer[] array) {
        return (int)IntStream.rangeClosed(0, array.length)
            .flatMap(index -> IntStream.range(0, index)
                .map(newIndex -> Arrays.stream(array,newIndex,index).mapToInt(x->x).sum())
                .filter(sum -> sum < 0))
            .count();
    }
}

这仍然具有与嵌套迭代相同的时间复杂度。如果您想优化执行时间,有状态操作更适合该任务,这不是 Stream API 的好用例。使用普通循环很简单:

private final static class SubarrayProcessorNegativeSumStrategy 
    implements SubarrayProcessorStrategy {
    @Override public Integer apply(Integer[] array) {
        int count=0;
        for(int index = 0; index < array.length; index++) {
            for(int newIndex = index, currSum = 0; newIndex < array.length; newIndex++) {
                currSum += array[newIndex];
                if(currSum < 0) count++;
            }
        }
        return count;
    }
}

关于performance - 使用 Java 8 查找连续子列表的负和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43908471/

相关文章:

c# - List<Object> 的 XML 序列化

Python Pandas key 错误 : 'the label is not in the [index]'

c# - C# => 运算符的作用是什么? (除了作为 lambda 运算符之外)

java - NoClassDefFoundError 当我使用 lambda 遍历字符串数组时

sql - 加快查询速度,一张大表和一张小表的简单内部连接

c# - 为什么 LINQ (c#) 与 Seq (f#) 之间存在性能差异

javascript - 如何使具有大型 cytoscape.js 网络的页面更具响应性

python - For循环调用urllib.urlopen().getcode()很慢

python - 使用列表和切片

javascript - 返回 Promise.all 不执行提供的 Promise