本文正在参加「Java主题月 - Java Debug笔记活动」,详情查看<活动链接>
提问:如何用Java实现python里的生成器函数?
我想在Java中实现一个Iterator,其行为类似于Python中的以下生成器函数:
def iterator(array):
for x in array:
if x!= None:
for y in x:
if y!= None:
for z in y:
if z!= None:
yield z
Java方面的x可以是多维数组或某种形式的嵌套集合。 我不确定这将如何工作。 有人能帮助我吗?
回答1:
出于同样的需要,为此写了一个类。这里有些例子:
Generator<Integer> simpleGenerator = new Generator<Integer>() {
public void run() throws InterruptedException {
yield(1);
// Some logic here...
yield(2);
}
};
for (Integer element : simpleGenerator)
System.out.println(element);
// Prints "1", then "2".
无限生成器也是可能的:
Generator<Integer> infiniteGenerator = new Generator<Integer>() {
public void run() throws InterruptedException {
while (true)
yield(1);
}
};
Generator类与Thread配合使用以产生项目。 通过重写finalize(),它可以确保在Generator不再被使用的情况下,也没有线程停留在周围。
表现显然不是很好,但也不是太差。 在我的双核i5 CPU @ 2.67 GHz的计算机上,可以在<0.03s内生产1000件产品。
该代码在GitHub上。 在这里,您还将找到有关如何将其作为Maven / Gradle依赖项包括在内的说明。
回答2:
Java确实没有生成器,但是您现在可以使用Java 8的Stream。
IMO确实是一个复杂的迭代器,因为它由数组(而不是函数)支持。给定它是一个循环,可以使用过滤器(跳过空值)和flatMap传递内部集合将其表示为Stream。
public class ArrayIterate
{
public static void main(String args[])
{
Integer[][][] a = new Integer[][][] { { { 1, 2, null, 3 },
null,
{ 4 }
},
null,
{ { 5 } } };
Iterator<Object> iterator = Arrays.stream(a)
.filter(ax -> ax != null)
.flatMap(ax -> Arrays.stream(ax)
.filter(ay -> ay != null)
.flatMap(ay -> Arrays.stream(ay)
.filter(az -> az != null)))
.iterator();
while (iterator.hasNext())
{
System.out.println(iterator.next());
}
}
}