我想用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
及其的方法。
提前致谢。
答案 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