重复方法,用Java8返回对象本身N次

时间:2015-05-20 08:22:59

标签: java lambda java-8

我想用Java 8风格实现以下代码:

public Path getSomeParent(Path path, int depth) {
    Path someParent = path;
    for (int i = 0; i < depth; i++) {
        someParent = someParent.getParent();
    }
    return someParent;
}

但是到目前为止没有运气,尽管我认为这个问题非常普遍。

第一个想法是使用reduce来做,但getParent()不是关联的,不是吗?

第二个是使用IntStream.range(0, depth),但我没有找到一种方法来完成这项任务。它适用于返回void及其的方法。

提前致谢。

4 个答案:

答案 0 :(得分:7)

如果真的希望,您可以使用

return Stream.iterate(path, Path::getParent).skip(depth).findFirst().get();

但我不推荐它。你的原始循环很好。

答案 1 :(得分:5)

而不是迭代,您可以使用NIO 2 API使用以下代码段(在Java 7中同样如此)。

Path path = Paths.get("/temp/some/dir/foo");
int depth = 2;

Path someParent = path.getRoot().resolve(path.subpath(0, path.getNameCount() - depth));

System.out.printf("%-10s: %s%n", "path", path);
System.out.printf("%-10s: %d%n", "depth", depth);
System.out.printf("%-10s: %s%n", "someParent", someParent);

<强>输出

path      : /temp/some/dir/foo
depth     : 2
someParent: /temp/some

答案 2 :(得分:2)

您仍然可以将reduce用于顺序流,因为此处不需要关联性:

return IntStream.range(0, depth).boxed()
        .reduce(path, (p, n) -> p.getParent(), 
                (p1, p2) -> { throw new UnsupportedOperationException(); });

虽然不推荐,因为它不适用于并行流。 某些第三方库提供foldLeft方法,在这种情况下更合适。

答案 3 :(得分:0)

我不知道究竟是什么&#34; Java8风格&#34;,但是,如果我们可以使用尾调用优化:

public Path getSomeParent(Path path, int depth) {
  if ( depth == 0 || path == null ) return path;
  return getSomeParent(path.getParent(), depth-1);
}

关于Java是否有尾部调用优化,请参阅此链接:http://www.drdobbs.com/jvm/tail-call-optimization-and-java/240167044