2016-07-07 99 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