有没有等同于 C# 的“yield”关键字的 Java?

新手上路,请多包涵

我知道 Java 本身没有直接的等价物,但也许是第三方?

真的很方便。目前我想实现一个生成树中所有节点的迭代器,这大约是五行带有 yield 的代码。

原文由 ripper234 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 616
2 个回答

我知道的两个选项是 2007 年 Aviad Ben Dov 的 infomancers-collections 库2008 年 Jim Blackler 的 YieldAdapter 库(另一个答案中也提到了)。

两者都允许您使用 yield return Java 构造来编写代码,因此两者都将满足您的要求。两者之间的显着差异是:

力学

Aviad 的库使用字节码操作,而 Jim 的库使用多线程。根据您的需要,每种可能都有自己的优点和缺点。 Aviad 的解决方案可能更快,而 Jim 的解决方案更便携(例如,我认为 Aviad 的库无法在 Android 上运行)。

界面

Aviad 的库有一个更简洁的界面——下面是一个例子:

 Iterable<Integer> it = new Yielder<Integer>() {
    @Override protected void yieldNextCore() {
        for (int i = 0; i < 10; i++) {
            yieldReturn(i);
            if (i == 5) yieldBreak();
        }
    }
};

虽然吉姆的方法要复杂得多,但需要您 adept 一个通用的 Collector 它有一个 collect(ResultHandler) 方法…呃。但是,您可以 通过 Zoom Information 在 Jim 的代码周围使用类似这样的包装器, 这大大简化了:

 Iterable<Integer> it = new Generator<Integer>() {
    @Override protected void run() {
        for (int i = 0; i < 10; i++) {
            yield(i);
            if (i == 5) return;
        }
    }
};

执照

Aviad 的解决方案是 BSD。

Jim 的解决方案是公共领域,上面提到的它的包装器也是如此。

原文由 Oak 发布,翻译遵循 CC BY-SA 3.0 许可协议

现在 Java 有了 Lambdas,这两种方法都可以变得更简洁一些。你可以做类似的事情

public Yielderable<Integer> oneToFive() {
    return yield -> {
        for (int i = 1; i < 10; i++) {
            if (i == 6) yield.breaking();
            yield.returning(i);
        }
    };
}

我在这里做了更多解释。

原文由 benjiweber 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题