【问题标题】:Passing objects through streams and flatmaps通过流和平面图传递对象
【发布时间】:2016-04-13 17:17:51
【问题描述】:

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

}

问题是我无法访问地图操作中的派对对象。 所以问题又是我能以更实用的方式做吗? (和第二种方法一样)

谢谢!

【问题讨论】:

  • 是的,hack 是将平面映射成一个元组流,其中包含成员及其派对。像.flatMap(party -&gt; party.getMembers().stream().map(member -&gt; new Tuple&lt;&gt;(party, member)) 这样的东西。而且由于没有内置的元组类,您可以自己制作或(ab)使用AbstractMap.SimpleEntry...
  • 或者 Pair.of(party, member) 来自 commons-lang 如果你已经有这个依赖。
  • @Tunaki:你想的太复杂了……

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


【解决方案1】:

你把太多的东西分解成单独的操作了:

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

这可以通过将两个map 步骤移动到flatMap 步骤中来工作,其中只有第二个存在,现在被应用于返回的“子流”。正如您问题的 cmets 所指出的,您需要某种 Pair 类型来将“子流”元素映射到,但您的 Elector 类型完全满足了这一点,因为它是使用您感兴趣的两个值构造的. 所以没有必要映射到一个通用的Pair(member,party) 只是为了映射到Elector 之后。

【讨论】:

【解决方案2】:

为了让所有内容保持可读性,我会在 Party 类中添加一个辅助方法(或其他地方的静态方法)以获取 Stream&lt;Elector&gt;:

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

【讨论】:

    猜你喜欢
    • 2018-09-11
    • 1970-01-01
    • 2013-03-28
    • 1970-01-01
    • 2012-10-04
    • 2023-03-30
    • 2017-09-11
    • 2018-04-20
    相关资源
    最近更新 更多