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

2022-08-31 09:15:46

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

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


答案 1

我所知道的两个选项是2007年的Aviad Ben Dov的信息手册馆藏库和2008年的Jim Blackler的YieldAdapter库(在另一个答案中也提到了这一点)。

两者都允许您使用Java中的类似构造编写代码,因此两者都将满足您的请求。两者之间的显着区别是:yield return

力学

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();
        }
    }
};

虽然Jim的要复杂得多,但需要您使用具有方法的通用...呸。但是,您可以通过Zoom Information在Jim的代码中使用类似这样的包装器,这大大简化了这一点:adeptCollectorcollect(ResultHandler)

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的解决方案是公共领域,上面提到的它的包装器也是如此。


答案 2

这两种方法都可以变得更干净,因为Java有Lambdas。你可以做这样的事情

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

我在这里解释了更多。


推荐