2016-11-15 84 views
1

我試圖端口下面的Python發電機到Java Iterator阻斷嵌套循環迭代器

def gen_sums(blocks1, blocks2): 
    for b1 in blocks1: 
    for b2 in blocks2: 
     for n1 in b1: 
     for n2 in b2: 
      yield n1 + n2 

在Java版本,界面看起來像:

public class Block { 
    ... 

    public Iterator<Integer> iterator() { ... } 
} 

public class GenSums implements Iterator<Integer> { 
    private Iterator<Block> blocks1; 
    private Iterator<Block> blocks2; 

    ... 

    @Override 
    public boolean hasNext() { /* TODO */ } 

    @Override 
    public Integer next() { /* TODO */ } 
} 

...我發現我很難找到正確的答案。在GenSums課程中只有很多州可以存儲,並從中恢復。在Java中是否有任何「標準」方式來實現這種迭代器?我想避免使用第三方庫。

+0

請參閱https://google.github.io/guava/releases/snapshot/api/docs/com/google/common/collect/Sets.html#cartesianProduct-java.util.Set...-如果您不喜歡不想使用庫,你必須保持狀態並自己重置「內部」迭代器。 – BadZen

+0

(當然,你可以隨時複製這個函數的源代碼......) – BadZen

回答

1

如果您使用的是Java 8,那麼您可能需要考慮生成一個流而不是迭代器。如果需要,可以將流轉換爲迭代器(使用BaseStream.iterator())。

因此,舉例來說:

class Block { 
    private final int[] b; 

    public IntStream getBs() { 
     return Arrays.stream(b); 
    } 
} 

public IntStream generate(List<Block> block1, List<Block> block2) { 
    return block1.stream() 
     .flatMapToInt(b1 -> block2.stream() 
      .flatMapToInt(b2 -> b1.getBs() 
       .flatMap(n1 -> b2.getBs().map(n2 -> n1 + n2))); 
} 

正如你所看到的,這是非常接近的Python相當於 - 的for語句成爲flatMapyield成爲map

+0

你需要爲'b1'和'b2'使用'flatMapToInt()'。 – shmosel

+0

@shmosel感謝您的取貨。固定。 – sprinter

+0

最後一行應該是'flatMap()',因爲它已經是'IntStream'了。 – shmosel