Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

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

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

It says "Incompatible return type Card in lambda expression"

like image 455
Brennan Hoeting Avatar asked Mar 26 '14 01:03

Brennan Hoeting


Video Answer


1 Answers

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 flatMap on primitives doesn't have any type-conversion overloads like flatMapToObj (doesn't exist);

  • assign to List rather than ArrayList as the Collectors methods 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 rangeClosed for this kind of situation.

like image 193
Maurice Naftalin Avatar answered Oct 13 '22 16:10

Maurice Naftalin