通过流和平面图传递对象

时间:2016-04-13 17:17:51

标签: java functional-programming java-8 java-stream

我正在处理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) {

    }

}

在我的第二种方法中,我尝试使用地图和平面图的操作:

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

}

问题是我无法访问map操作中的party对象。 所以问题是我能以更实用的方式做吗? (像第二种方法)

谢谢!

2 个答案:

答案 0 :(得分:6)

您将过多的分解为个别操作:

   function time_get()
   {
        var selected = document.getElementById("select_post_id");
        var selectedVal = selected.options[selected.selectedIndex].value;
       if(selectedVal != ""){
          //do whatever
       }else{alert('select an option');}
    }

这可以通过将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)

答案 1 :(得分: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));
}

然后在平面地图中使用它

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