2015-12-03 50 views
1

如何/我可以更改以下方法以使用流?java 8以前值的lambda

在命令式编程风格中,我存储了以前的城市值,并不得不使用它来获取下一个值,参见e.getOther()(别问我为什么)。

问题的重点是:如何使用streams/lambda实现相同的输出?

private <V extends City, E extends WeightedEdge<V>> void printWeightedEdgePath(List<E> pathList, V srcVertex, V destVertex) { 
    PrintVisitor printVisitor = new PrintVisitor(); 
    if (!pathList.isEmpty()) { 
     V atThisCity = srcVertex; 
     System.out.printf("%s to %s: %s", srcVertex, destVertex, srcVertex); 
     pathList.stream().forEach(edge -> { // stream way - error 
      printVisitor.accept(edge); 
      System.out.printf(" --%2.2f-->", e.weight()); 
      atThisCity = e.getOther(atThisCity); // variable must be final 
      printVisitor.accept(atThisCity); 
     }); 
     System.out.println(); 
    } else { 
     System.out.printf("%s to %s: not connected\n", srcVertex, destVertex); 
    } 
    System.out.println(); 
} 

编辑:感谢@Bohemian技巧 - 作弊的java最终使用数组obj。

private <V extends City, E extends Edge<V>> void printEdgePath(List<E> pathList, V srcVertex, V destVertex) { 
    PrintVisitor printVisitor = new PrintVisitor(); 
    if (!pathList.isEmpty()) { 
     Vertex [] atThisCity = new Vertex[]{srcVertex}; 
     System.out.printf("%s to %s: %s", srcVertex, destVertex, srcVertex); 
     pathList.stream().forEach(edge -> { 
      printVisitor.accept(edge); 
      @SuppressWarnings("unchecked") 
      V nextCity = edge.getOther((V)atThisCity[0]); 
      atThisCity[0] = nextCity; 
      printVisitor.accept(atThisCity[0]); 
     }); 
     System.out.println(); 
    } else { 
     System.out.printf("%s to %s: not connected\n", srcVertex, destVertex); 
    } 
    System.out.println(); 
} 
+0

我不认为lambda表达式是这一个正确的选择 - 以前的城市参考最终成为你的程序中的状态。您可以创建一个Consumer的实现,您可以拥有一个City实例变量--forEach调用可以引用Consumer接口 – romeara

回答

1

这里有一个变通规避了“最后有效”的要求:

如果您需要在拉姆达修改的值,使用数组。虽然数组是最终的,但其内容可能会发生变异。即:

Object[] array = new Object[1]; 
someStream.forEach(o -> {processPreviousAndCurrent(array[0], o); array[0] = o;}); 

在这个微不足道的例子中,数组保存了以前的值。

在你的榜样,这样做:

private <V extends City, E extends WeightedEdge<V>> void printWeightedEdgePath(List<E> pathList, V srcVertex, V destVertex) { 
    PrintVisitor printVisitor = new PrintVisitor(); 
    if (!pathList.isEmpty()) { 
     Object[] atThisCity = new Object[]{srcVertex}; 
     System.out.printf("%s to %s: %s", srcVertex, destVertex, srcVertex); 
     pathList.stream().forEach(edge -> { 
      printVisitor.accept(edge); 
      System.out.printf(" --%2.2f-->", e.weight()); 
      atThisCity[0] = e.getOther((V)atThisCity[0]); 
      printVisitor.accept(atThisCity); 
     }); 
     System.out.println(); 
    } else { 
     System.out.printf("%s to %s: not connected\n", srcVertex, destVertex); 
    } 
    System.out.println(); 
}