Transferring objects through streams and maps

I am dealing with Java 8 threads, and I am wondering if I can solve this problem in a fancy way.

What is my scenario: Suppose I have a list of parties, and inside each element I have member names. I want to iterate over the list and create a new one with names and which side they belong to.

My first approach:

@Test public void test(){ Party firstParties = new Party("firstParty",Lists.newArrayList("Member 1","Member 2","Member 3")); Party secondParty = new Party("secondParty",Lists.newArrayList("Member 4","Member 5","Member 6")); List<Party> listOfParties = Lists.newArrayList(); listOfParties.add(firstParty); listOfParties.add(secondParty); List<Elector> electors = new ArrayList<>(); listOfParties.stream().forEach(party -> party.getMembers().forEach(memberName -> electors.add(new Elector(memberName,party.name)) ) ); } class Party { List<String> members = Lists.newArrayList(); String name = ""; public Party(String name, List<String> members) { this.members = members; this.name = name; } public List<String> getMembers() { return members; } } class Elector{ public Elector(String electorName,String partyName) { } } 

In my second approach, I tried using cards with flat cards:

 @Test public void test(){ Party firstParty = new Party("firstParty",Lists.newArrayList("Member 1","Member 2","Member 3")); Party secondParty = new Party("secondParty",Lists.newArrayList("Member 4","Member 5","Member 6")); List<Party> listOfParties = Lists.newArrayList(); listOfParties.add(firstParty); listOfParties.add(secondParty); List<Elector> people = listOfParties.stream().map(party -> party.getMembers()) .flatMap(members -> members.stream()) .map(membersName -> new Elector(membersName, party.name)) #Here is my problem variable map doesn't exist .collect(Collectors.toList()); } 

The problem is that I cannot access the member object inside the map operation. So again, the question is: can I make a more functional way? (like the second approach)

Thanks!

+5
source share
2 answers

You have decomposed too much into separate operations:

 List<Elector> people = listOfParties.stream() .flatMap(party -> party.getMembers().stream() .map(membersName -> new Elector(membersName, party.name))) .collect(Collectors.toList()); 

This works by moving both map steps to the flatMap step, where only the second survives, now applies to the returned "subflow". As stated in the comments on your question, you need some type of Pair to map the elements of the "subflow", but your type Elector does just that, since it is built using two values ​​that interest you. Therefore, there is no need to match the common Pair(member,party) only for display on Elector .

+5
source

To make everything readable, I would add a helper method in the Party class (or a static method elsewhere) to get a Stream<Elector> :

 public Stream<Elector> electors() { return getMembers().stream().map(member -> new Elector(member, name)); } // Alternatively public static Stream<Elector> electors(final Party p) { return p.getMembers().stream().map(member -> new Elector(member, p.name)); } 

And then just use this in your layout

 final List<Elector> people = listOfParties.stream() .flatMap(Party::electors) .collect(Collectors.toList()); 
+2
source

Source: https://habr.com/ru/post/1247061/


All Articles