将逻辑转换为流 (Java)(嵌套 for 循环与计数器)

Convert logic to Streams (Java) (nested for loops with counter)

亲爱的,

我是 Streams 的新手,想将一些逻辑转换为使用它们:

逻辑是这样的:

    for (String headerKey : map.keySet()) {
        int counter = 1;
        for (String value : map.get(headerKey)) {
            if (map.get(headerKey).size() != 1) {
                System.out.println("Response header: " + headerKey + "[" + counter++ + "]: " + value);
            } else {
                System.out.println("Response header: " + headerKey + ": " + value);
            }
        }
    }

问题出在“计数器”...

我得到了:

private static long after(Map<String, List<String>> map) {

    return map.keySet().stream().map(key -> output(key, map)).count(); // use print() here instead of output()
}

private static String output(String key, Map<String, List<String>> map) {

    counter = 1;

    long longString = map.get(key).stream().map(value -> print(value, key, map.get(key))).count();

    return "" + longString;
}

private static String print(String value, String key, List<String> strings) {

    if (strings.size() != 1) {
        System.out.println("Response header: " + key + "[" + counter++ + "]: " + value);
    } else {
        System.out.println("Response header: " + key + ": " + value);
    }

    return "";
}

而且我想我可以将 print() 方法放在指定的位置,

但我不知道如何让计数器的行为与原始代码中的一样...

欢迎所有 comment/ideas :)

谢谢!

像这样创建一个辅助方法

static Stream<String> values(List<?> list) {
    return list.size() == 1? Stream.of(": " + list.get(0)):
        IntStream.range(0, list.size()).mapToObj(ix -> "[" + ix + "]: " + list.get(ix));
}

它不是在每次迭代中重新评估 list.size() == 1 条件,而是预先选择正确的操作形状。当大小不是一个时,与其尝试维护一个计数器,不如首先流过索引范围。

现在可以在地图上流式传输时使用此方法,例如

map.entrySet().stream()
    .flatMap(e -> values(e.getValue()).map(("Response header: " + e.getKey())::concat))
    .forEach(System.out::println);