2016-04-13 21 views
5

我正在处理Java 8流,我想知道我是否可以用奇特的方式解决这个问题。通过流和平面图传递对象

这就是我的场景: 假设我有一个派对的列表,并且在每个元素中都有成员的名字。我想遍历列表并使用名称和属于哪个方来创建一个新列表。

我的第一种方法是:

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

    } 

} 

在我的第二个方法我试过用映射的flatmap的操作:

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

} 

的问题是我无法访问党物体内地图操作。 所以问题再次是我可以做更多功能的方式? (如第二种方法)

谢谢!

+0

是的,黑客将平面映射到一个元组流中,该元组将包含成员及其派对。就像'.flatMap(party - > party.getMembers()。stream()。map(member - > new Tuple <>(party,member))'。因为没有内置的元组类,所以你可以你自己或(ab)使用'AbstractMap.SimpleEntry' ... – Tunaki

+0

或者'Pair.of(party,member)'from commons-lang如果你已经拥有这个依赖关系。 –

+2

@Tunaki:你想太复杂了... – Holger

回答

5

您分解过多成单独的操作:

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

这是通过移动两个map步入flatMap工序,变成只有第二个生存,现在被应用到返回的“子”。正如你的问题的评论中指出的那样,你需要某种Pair类型来映射“子流”元素,但是你的Elector类型正好满足这个要求,因为它是用你感兴趣的两个值构造的。之后不需要映射到通用Pair(member,party)只是为了映射到Elector

2

把一切都可读我想补充的Party类的辅助方法(或静态方法在其他地方)获得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)); 
} 

,然后只用在你的flatmap

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