2016-07-07 69 views
-1

我想使用番石榴迭代器或java8 foreach(可能是lambda表达式)嵌套循环和处理一些语句并返回一个长变量。这是我的原生Java代码。请原谅我的代码可能效率不高。我读过网访问新的java 8 foreach中的非最终变量是不可能的。番石榴迭代器嵌套的foreach

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; 

我试过了,但无法返回值。预先感谢您的帮助!

+0

所以水平只是为了跟踪通过循环的次数? –

+0

并尝试像x + = getSomeValue(x)//但它应该是getSomeValue(第一个)? –

回答

3

两件事情:

  1. 之前接近“重构”这样的一个你问,我真的强烈建议学习更“纯”的Java(我假设这里的情况,@javalearner)。例如,你可以使用long文字手动拳击值,而不是:

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

    反正...利用番石榴不会帮助这里

  2. - 这是做的势在必行方式,并与Java 7 +番石榴,你必须写出尴尬的匿名类(即Function),没有语言支持是痛苦的。这使我想到...
  3. Java 8和Streams。这可能是最好的方式,但首先你必须要修好你的代码,并确定实际的问题(?) - 例如本声明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(); 
} 
+0

对不起。我错了。你的第三点是正确的。我现在编辑过。如果它不可能在番石榴上,是否有可能在Java 8 forEach中使用lamda表达式?至少我需要避免原生的forloop语法。感谢您的答复。非常赞赏 – javalearner

+0

我认为使用java8将是效率和看起来不错。有没有其他办法? – javalearner

+0

@javalearner我添加了流版本。 – Xaerxess

1

首先,有是没有意义的使用盒装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的结果,是集合可以相同流操作写成

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),同样,如果getSecondLevels()返回一个数组,则必须用替换

+0

使用'LongStream#concat'和'Stream#flatMapToLong'的好方法! – Xaerxess

+0

@Xaerxess:是的,'flatMap'方法对于终端操作可能变得不重要。 – Holger