如何在Java 8中创建连接列表?

时间:2016-05-01 17:02:49

标签: java java-8

我有两个String列表,一个来自节点的右子树,另一个来自该节点的左子树。列表中任何一个中的每个字符串实际上都是以逗号分隔的整数列表。

现在我需要创建一个包含以下内容的新列表:

  • 开始时 em 的值
  • 后跟逗号
  • 后跟从leftList
  • 中挑选的字符串
  • 后跟逗号
  • 后跟一个字符串选择形式rightList

所以,如果rightList有:

  • 1,2,3,4,5
  • 1,4,5,2,3

并且leftList具有:

  • 7,8,6,98,12
  • 7,98,12,8,6

并且节点处的值为10,输出列表应为:

  • 10,7,8,6,98,12,1,2,3,4,5
  • 10,7,8,6,98,12,1,4,5,2,3
  • 10,7,98,12,8,6,1,2,3,4,5
  • 10,7,98,12,8,6,1,4,5,2,3
  • 10,1,2,3,4,5,7,8,6,98,12
  • 10,1,2,3,4,5,7,98,12,8,6
  • 10,1,4,5,2,3,7,8,6,98,12
  • 10,1,4,5,2,3,7,98,12,8,6

我不难使用传统的 for-each 用于循环。实际上,这是一个实现:

public ArrayList<String> getList (Node n) {

    //Prepare leftList and rightList...

    if (leftList.size() == 0) return prepareSingleList(sb, v, rightList);
    if (rightList.size() == 0) return prepareSingleList(sb, v, leftList);

    //TODO: re-write this code to use Stream API

    ArrayList<String> myList = new ArrayList<>();
    StringBuilder sb = new StringBuilder();

    //both lists are non-empty, so run two loops    
    for (String l: leftList) {
        for(String r: rightList) {
            sb.setLength(0);
            appendValues(v, l, r, sb);
            myList.add(sb.toString());
            sb.setLength(0);
            appendValues(v, r, l, sb);
            myList.add(sb.toString());
        }
    }
    return myList;
}

private void appendValues(int v, String s1, String s2, StringBuilder sb) {
    sb.append(v);
    sb.append(",");
    sb.append(s1);
    sb.append(",");
    sb.append(s2);
}

问题:我正在尝试了解Java-8中的流API和lambda表达式。如何使用Stream API重新编写//TODO:...部分代码之后编写的代码?

1 个答案:

答案 0 :(得分:3)

如果我理解正确,您有List<String>leftListList<String> rightList。并且您希望使用Stream API生成leftListrightList中的所有元素对。

这将是更具可读性,IMO,有两个嵌套循环,但您可以使用flatMap来实现相同的结果:

leftList.stream()
        .flatMap(left -> rightList.stream()
                                  .map(right -> left + "," + right))
        .collect(Collectors.toList());

如果你想在两个方向上拥有对,你可以做到

leftList.stream()
        .flatMap(left -> rightList.stream()
                                  .flatMap(right -> Stream.of(left + "," + right, 
                                                              right + "," + left))
        .collect(Collectors.toList());

但是,正如评论中已经指出的那样,将所有内容表示为字符串会适得其反。如果你有一个包含两个元素的Pair类,而不是字符串连接,你可以在对列表上迭代两次,并在左侧节点左侧显示一次,在右侧显示左侧节点一次。