簡體   English   中英

在Java 8中使用flatmap編寫流

[英]Composing streams with flatmap in Java 8

我們考慮一下我有以下課程:

class A {
   int i, j, k;

   public A(int i, int j, int k) {
     this.i = i; this.j = j; this.k = k;
   }
}

其中ijk具有已知范圍: r_ir_jr_k 現在我想在此范圍內生成A所有可能實例。 我可以想出類似的東西:

Stream.iterate(0, n -> ++n).limit(r_i)
.flatMap(i -> Stream.iterate(0, n -> ++n).limit(r_j)
.flatMap(j -> Stream.iterate(0, n -> ++n).limit(r_k)
.map(k -> new A(i, j, k)))).collect(Collectors.toList())

首先,它太冗長了。 有沒有辦法縮短它? 特別是我在Stream上找不到range 其次,編譯器無法確定返回類型的類型。 它將其視為List<Object>而不是預期的List<A> 我該如何解決這個問題?

使用range一種方法是在之后執行拳擊轉換:

List<A> list=IntStream.range(0, r_i).boxed()
  .flatMap(i -> IntStream.range(0, r_j).boxed()
    .flatMap(j -> IntStream.range(0, r_k)
      .mapToObj(k -> new A(i, j, k)))).collect(Collectors.toList());

它不是最漂亮的代碼,但IntStream.range(0, max).boxed()仍然比Stream.iterate(0, n -> n+1).limit(max) ...


一種替代方法是使用實​​際展平操作而不是嵌套操作:

List<A> list=IntStream.range(0, r_i).boxed()
  .flatMap(i  -> IntStream.range(0, r_j).mapToObj(j -> new int[]{i,j}))
  .flatMap(ij -> IntStream.range(0, r_k).mapToObj(k -> new A(ij[0], ij[1], k)))
  .collect(Collectors.toList());

我看到的主要缺點是它缺少IntPairTuple<int,int>類型。 所以它使用數組作為解決方法。

如果有可變變量,你可以像這樣獲得A類的List ....

List<A> newCollect = new ArrayList<>();
IntStream.range(0, r_i).forEach(
    i -> IntStream.range(0, r_j).forEach(
        j -> IntStream.range(0, r_k).forEach(
            k -> newCollect.add(new A(i, j, k))
        )
    )
);

或者你可以制作A列表列表,然后像這樣兩次flatMap ...

List<A> newCollect2 = IntStream.range(0, r_i).mapToObj(
    i -> IntStream.range(0, r_j).mapToObj(
        j -> IntStream.range(0, r_k).mapToObj(
            k -> new A(i, j, k)
        ).collect(Collectors.toList())
    ).collect(Collectors.toList())
)
.flatMap(a -> a.stream())
.flatMap(a -> a.stream())
.collect(Collectors.toList());

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM