2017-08-03 123 views
2

比方說,我有一個int數組,我想找到總和爲零的所有對。在過去,我會做這樣的事情:如何將嵌套循環轉換爲嵌套流?

public static int count(int[] a) { 
    int cnt = 0; 
    int N = a.length; 
    for (int i = 0; i < N; i++) { 
     for (int j = i + 1; j < N; j++) { 

     if (a[i] + a[j] == 0) { 
      cnt++; 
     } 
     } 
    } 
    return cnt; 
    } 

現在我有一些麻煩轉換爲流。

我嘗試以下方法,但我得到一個IllegalStateException異常:

final IntStream stream1 = Arrays.stream(a); 
final IntStream stream2 = Arrays.stream(a); 
long res = stream1.flatMap(i -> stream2.filter(j -> (j + i == 0))).count(); 
+0

的IllegalStateException異常是不是我的問題。我明白那個。這是我翻譯嵌套到流的困難的後果。我的問題是如何轉換嵌套在流 – MLeiria

+0

PLZ編輯的問題,然後我會在這種情況下重新打開 – Eugene

+0

@MLeiria我投票重新打開並更改標題 –

回答

5

變化stream2.filterArrays.stream(a) - 流將被關閉,第二次你會嘗試對其進行處理。

但你不計算正確,無論如何,它應該是:

IntStream.range(0, a.length) 
      .flatMap(x -> Arrays.stream(a).skip(x + 1).filter(j -> j + a[x] == 0)) 
      .count(); 
+0

就是這樣!謝謝。不知道有關「跳過」。仍然讓我的頭在Java 8(這是很好的方式) – MLeiria

+0

我已經得到它。謝謝 – MLeiria

+0

當然,@Eugene。好的東西在答案中。 – MLeiria

5

Streams是不可重複使用的所以你不能定義一次,並保持重用。這就是爲什麼將它們存儲在變量中被認爲是不好的做法。

你需要當場創建它們:

long res = Arrays.stream(a) 
    .flatMap(i -> Arrays.stream(a).filter(j -> (j + i == 0))) 
    .count(); 

此外,爲了充分體現提供的實現,避免重複,你將需要skip一些元素在每個嵌套Stream開頭:

long res = IntStream.range(0, a.length) 
    .flatMap(i -> Arrays.stream(a).skip(i + 1).filter(j -> (j + a[i] == 0))) 
    .count(); 

如果你想提取到的變量,你需要使用一個Supplier這將作爲我們的工廠Streams。每個get調用創建一個新的Stream實例:

final Supplier<IntStream> s =() -> Arrays.stream(a); 
long res = s.get() 
    .flatMap(i -> s.get().filter(j -> (j + i == 0))) 
    .count(); 
+0

謝謝。它不同的是流方法反覆計數。在嵌套方式中,內部循環比外部循環先行一步,所以它不會重複計數。例如,如果int [] a = new int [] {1,2,3,4,-3,5,-5};'嵌套的for給出2的結果,這是正確的,因爲只有兩個元素3,-3)和(5,-5),但流給出了4的結果 – MLeiria

+0

@MLeiria我會更新答案 –