Java 8 Lambda:我可以从IntStream生成一个新的对象ArrayList吗?

Bre*_*ing 12 java lambda java-8

我有一个卡类

public class Card {

   private int value, suit;

   public Card(int value, int suit) {
       this.value = value;
       this.suit = suit;
   }

   //gets, sets, toString
}
Run Code Online (Sandbox Code Playgroud)

这就是我通常填充CardList的方法

for(int suit = 1; suit <= 4; ++suit)
    for(int value = 1; value <= 13; ++value)
        Cards.add(new Card(value, suit));
Run Code Online (Sandbox Code Playgroud)

但我想使用Lambda表达式来初始化它

ArrayList<Card> Cards = IntStream.range(1, 4)
                           .map(value -> IntStream.range(1, 13)
                               .map(suit -> new Card(value, suit)));
Run Code Online (Sandbox Code Playgroud)

Intellij正在给我一个错误 .map(suit -> new Card(suit, value))

它说"lambda表达式中不兼容的返回类型卡"

Mau*_*lin 29

这就是你想要的:

List<Card> cards = IntStream.rangeClosed(1, 4)
    .boxed()
    .flatMap(value -> 
        IntStream.rangeClosed(1, 13)
            .mapToObj(suit -> new Card(value, suit))
    )
    .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

注意事项:

  • 你必须打包整数,因为flatMap在原语上没有任何类型转换重载,如flatMapToObj(不存在);

  • 分配给List而不是ArrayList作为Collectors方法不保证它们返回的特定类型(因为它现在发生 ArrayList,但你不能依赖它);

  • 使用rangeClosed了这种情况.


srb*_*gan 5

获得您想要的东西的另一种方法(基于莫里斯·纳夫塔林的答案):

List<Card> cards = IntStream.rangeClosed(1, 4)
  .mapToObj(value -> IntStream.rangeClosed(1, 13)
    .mapToObj(suit -> new Card(value, suit))
  )
  .flatMap(Function.identity())
  .collect(Collectors.toList())
;
Run Code Online (Sandbox Code Playgroud)

其他注意事项:

  • 您必须将int值映射到Stream流,然后通过Function.identity()将flatMap表示为流,因为flatMapToObj不存在,但是所述操作可以转换为Map的映射,然后可以转换为FlatMap的标识。

  • 与我的解决方案相比,我更喜欢这个,尽管@skiwi 上面的评论仍然有效——命令式版本仍然更好。 (2认同)