【问题标题】:Iterating Java Arrays with Streams使用流迭代 Java 数组
【发布时间】:2022-12-01 08:17:41
【问题描述】:

所以这是一个简单的算法问题,

给定一个整数列表,检查此列表中是否有两个数字相加后得到八 (8)。

这是我的解决方案,

import java.util.List;

public class Main {

    static List<Integer> arrayOne = List.of(1,3,6,9);
    static List<Integer> arrayTwo = List.of(1,6,2,10);

    static boolean validateArray(int result, List<Integer> array){
        for (int i = 0; i<array.size() - 1; i++){
            for (int j = i + 1; j < array.size(); j ++){
                int value1 = array.get(i);
                int value2 = array.get(j);
                if(value1 + value2 == result){
                    return true;
                }
            }
        }
        return false;
    }

    public static void main(String[] args) {

        System.out.println(validateArray(8, arrayTwo));
    }
}

这很好用。我想学习的是如何在 Java 8 中重写这段代码。就像 Java 8 中循环的不同选项一样。

【问题讨论】:

  • 流对于将一个元素与流的其余部分进行比较并不是很好。有 #max#sorted 之类的边缘情况,但总体而言,与上面的代码相比,使用流执行此操作的解决方案将非常复杂。

标签: arrays java-8 java-stream


【解决方案1】:

无论实现(流或循环) 对列表中的每个元素对整个列表执行暴力迭代并不是解决此问题的最佳方法。

我们可以通过生成给定列表中元素频率的映射来索引元素。然后我们可以迭代 Map 的键,检查每个键是否对应的键,等于 result - key 存在于 Map 中。

但是,我们需要解决一种极端情况:

  • 如果result 是偶数并且列表中只有一个元素等于result / 2 检查地图中是否存在result - key 是不够的,在这种情况下我们需要更改关联的值钥匙。

如果您想首先使用 Stream API 生成地图,您可以使用收集器 groupingBy()counting() 的组合。然后在 Map 的键上创建一个流并应用 anyMatch() 操作以获得 boolean 结果:

static boolean validateArray(int result, List<Integer> array) {
    Map<Integer, Long> countByNum = array.stream()
        .collect(Collectors.groupingBy(
            Function.identity(),
            Collectors.counting()
        ));
    
    return countByNum.keySet().stream()
        .anyMatch(key -> key * 2 == result ?
            countByNum.get(key) >= 2 : countByNum.containsKey(result - key)
        );
}

【讨论】:

    猜你喜欢
    • 2021-06-25
    • 1970-01-01
    • 1970-01-01
    • 2023-01-28
    • 1970-01-01
    • 2018-07-28
    • 1970-01-01
    • 2018-12-19
    • 2011-04-23
    相关资源
    最近更新 更多