用于嵌套 foreach 的 Guava 迭代器

Guava iterators for nested foreach

我想使用 guava 迭代器或 java8 foreach(可能是 lambda 表达式)嵌套 for 循环并处理一些语句和 return 一个长变量。这是我的原生代码 java。请原谅我的代码可能效率不高。我通过网络阅读了 new java 8 foreach 中的非 final 变量是不可能的。

Long x = Long.valueOf(0);
Long y = Long.valueOf(0);
for(FirstLevel first : Levels) 
{
   if(first.getSecondLevels() == null) 
   {   
      x= x + getSomeValue(first);
   }
     for (SecondLevel second : first.getSecondLevels())
   {
      y = y + getSomeValue(second);
   }
}
return x + y;

我已尝试但无法 return 这些值。在此先感谢您的帮助!

两件事:

  1. 在像你问的那样接近 "refactoring" 之前,我强烈建议你多学习 "pure" Java(我假设这里就是这种情况,@javalearner ).例如,您可以使用 long 文字而不是手动装箱值:

    long x = 0L;
    long y = 0L;
    

    总之...

  2. 在这里使用 Guava 无济于事 - 这是 的必要方式,使用 Java 7 + Guava 你必须写出笨拙的匿名类(即 Functions),没有语言支持是痛苦的。这让我想到...
  3. Java 8 和流。这可能是最好的方法,但首先你必须修复(?)你的代码并定义实际问题 - 例如这个语句 x= x + getSomeValue(x); 每次评估 x 并且不采用 FirstLevel 考虑在内(ySecondLevel 也是如此),所以我假设你真正的意思是 x =+ getSomeValue(firstLevel);.

综上所述 - 请更具体地说明您的问题到底是什么。

编辑:

在您澄清之后,使用流您的代码可能如下所示:

final long sum = levels.stream()
        .mapToLong(first -> getSomeValue(first) + first.getSecondLevels().stream().mapToLong(this::getSomeValue).sum())
        .sum();

或使用一些辅助方法:

final long s = levels.stream()
        .mapToLong(first -> getSomeValue(first) + getSecondLevelSum(first))
        .sum();

private long getSecondLevelSum(final FirstLevel first) {
    return first.getSecondLevels().stream().mapToLong(this::getSomeValue).sum();
}

首先,使用盒装 Long 值没有任何意义,即使您曾经需要盒装值,也不需要调用 Long.valueOf、Java在将 long 基元转换为盒装 Long 对象时已经为您完成了。

此外,由于添加 long 值不依赖于被加数的顺序,因此没有理由在整个操作过程中维护两个变量,无论如何你都会在最后添加它们:

long result=0;
for(FirstLevel first: Levels) {
    result += getSomeValue(first);
    for(SecondLevel second: first.getSecondLevels()) {
        result += getSomeValue(second);
    }
}
return result;

注意运算符+=result = result + …的作用相同,但避免了目标操作数的重复。

假设 LevelsgetSecondLevels 的结果都是集合,你可以像

一样编写 Stream 操作
return Levels.stream()
    .mapToLong(first ->
        getSomeValue(first) + first.getSecondLevels().stream()
            .mapToLong(second -> getSomeValue(second)).sum())
    .sum();

或者,或者,

return Levels.stream()
    .flatMapToLong(first -> LongStream.concat(
        LongStream.of(getSomeValue(first)),
        first.getSecondLevels().stream().mapToLong(second -> getSomeValue(second))))
    .sum();

如果 Levels 是一个数组,你必须用 Arrays.stream(Levels) 替换 Levels.stream() 同样,如果 getSecondLevels() returns 是一个数组,你必须将 first.getSecondLevels().stream() 替换为 Arrays.stream(first.getSecondLevels())