0

I have a two classes Formulary and Pieces. Formulary has to keep a list of Pieces, because it is a formulary of pieces and I need to keep track of which Pieces Objects are in a Formulary:

class Piece {
    String id;
    String name;
    String info;
}

class Formulary{
    String id;
    TreeMap<String, Piece> pieces;
    
    public Collection<Piece> getPieces() {return pecas.values();}
}

Formulary has a method getPieces() to return the list of pieces it has contained.

It happens that I need to join pieces that are in multiple formularies. This is what i did so far:

 TreeMap<String, Formulary> forms;    
 List<Collection<Pieces>> piecesFromForms = forms.values().stream().map(Formulary::getPieces).collect(Collectors.toList())

The problem is that I was only capable to return a list<Collection<Pieces>>, but need to join all the list of pieces in the forms and return a List<Pieces> and I couldn't find a way to do this with collections.

I could do with for loops. I know, but I'm trying to get better with collections, as they work much faster.

Lino
  • 19,604
  • 6
  • 47
  • 65
Cesar Lopes
  • 373
  • 1
  • 10
  • I think `flatMap` is what you're looking for – Jeroen Steenbeeke Oct 03 '22 at 13:58
  • Thank you for the tip Jeroen, but I just started to use Collections, I used to make hundreds of For loops in my code, I'm refractoring everything. The simple ones I can do for sure, but when It starts to become hacky I don't know very much about colletions yet. If you could give an example I'd appreciate – Cesar Lopes Oct 03 '22 at 14:01

2 Answers2

2

You can use Stream.flatMap(), which expects a function which turns a new stream out of each stream element.

List<Piece> piecesFromForms = forms.values().stream()
    .flatMap(formulary -> formulary.getPieces().stream())
    .toList(); // for Java 16 or collect(Collectors.toList())

Or Java 16 Stream.mapMulti(), which might perform better if collection of Piece objects contained within each Formulary is tiny (literally a couple of elements or might be empty at all).

List<Piece> piecesFromForms = forms.values().stream()
    .<Piece>mapMulti((formulary, consumer) -> formulary.getPieces().forEach(consumer))
    .toList();
Alexander Ivanchenko
  • 25,667
  • 5
  • 22
  • 46
0

Use

List<Collection<Pieces>> piecesFromForms = forms.values()
    .stream()
    .Map(Formulary::getPieces)
    .flatMap(Collection::stream)
    .collect(Collectors.toList());
talex
  • 17,973
  • 3
  • 29
  • 66