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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22649978/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 17:06:04  来源:igfitidea点击:

Java 8 Lambda: Can I generate a new ArrayList of objects from an IntStream?

javalambdajava-8

提问by Brennan Hoeting

I have a Card class

我有一个卡片类

public class Card {

   private int value, suit;

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

   //gets, sets, toString
}

This is how I would normally fill the ArrayList of Card

这就是我通常填充 Card ArrayList 的方式

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

But I want to use a Lambda expression to initialize it

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

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

Intellij is giving me an error under .map(suit -> new Card(suit, value))

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

It says "Incompatible return type Card in lambda expression"

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

采纳答案by Maurice Naftalin

This is what you want:

这就是你想要的:

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

Points to note:

注意事项:

  • you have to box the ints because flatMapon primitives doesn't have any type-conversion overloads like flatMapToObj(doesn't exist);

  • assign to Listrather than ArrayListas the Collectorsmethods make no guarantee as to the specific type they return (as it happens it currently is ArrayList, but you can't rely on that);

  • use rangeClosedfor this kind of situation.

  • 您必须将整数装箱,因为flatMap在原语上没有任何类型转换重载,例如flatMapToObj(不存在);

  • 分配给List而不是ArrayList因为这些Collectors方法不能保证它们返回的特定类型(因为它目前是这样 ArrayList,但你不能依赖它);

  • 使用rangeClosed了这种情况。

回答by srborlongan

Another way to get what you want (based on Maurice Naftalin's answer):

另一种获得您想要的东西的方法(基于 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())
;

Additional points to note:

补充注意事项:

  • you have to map the int values to Stream streams, then flatMap said streams via Function.identity(), since flatMapToObj does not exists, yet said operation is translatable to a map to Stream, then an identity flatMap.
  • 您必须将 int 值映射到 Stream 流,然后通过 Function.identity() 将所述流映射到 flatMap,因为 flatMapToObj 不存在,但所述操作可转换为映射到 Stream,然后是身份 flatMap。