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

2022-09-03 17:19:24

我有一个卡片类

public class Card {

   private int value, suit;

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

   //gets, sets, toString
}

这就是我通常填写卡的数组列表的方式

for(int suit = 1; suit <= 4; ++suit)
    for(int value = 1; value <= 13; ++value)
        Cards.add(new Card(value, suit));

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

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

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

它显示“lambda 表达式中的不兼容返回类型卡”


答案 1

这是你想要的:

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

注意事项:

  • 你必须框住int,因为在基元上没有任何类型转换重载,比如(不存在);flatMapflatMapToObj

  • 赋值给而不是因为方法不保证它们返回的特定类型(碰巧它目前是,但你不能依赖它);ListArrayListCollectorsArrayList

  • 用于这种情况。rangeClosed


答案 2

另一种获得你想要的东西的方法(基于Maurice Naftalin的答案):

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())
;

需要注意的其他要点:

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

推荐