Eqb*_*bal 38 python java iterator generator
我想Iterator在Java中实现一个与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
Run Code Online (Sandbox Code Playgroud)
java端的x可以是多维数组或某种形式的嵌套集合.我不确定这是如何工作的.想法?
Mic*_*ann 42
有同样的需要,所以写了一个小课程.这里有些例子:
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".
Run Code Online (Sandbox Code Playgroud)
无限发电机也是可能的:
Generator<Integer> infiniteGenerator = new Generator<Integer>() {
public void run() throws InterruptedException {
while (true)
yield(1);
}
};
Run Code Online (Sandbox Code Playgroud)
在Generator类内部有主题的作品产生的项目.通过覆盖finalize(),它确保如果不再使用相应的Generator,则不会留下任何线程.
表现显然不是很好,但也不是太破旧.在配备双核i5 CPU @ 2.67 GHz的机器上,可以在<0.03秒内生成1000个项目.
代码在GitHub上.在那里,您还可以找到有关如何将其作为Maven/Gradle依赖项包含的说明.
The*_*der 18
事实上,Java没有收益,但您现在可以使用Java 8流.IMO它真的是一个复杂的迭代器,因为它是由数组支持的,而不是函数.鉴于它是循环中循环的循环,可以表示为使用过滤器的流(跳过空值)和flatMap来流式传输内部集合.它也与Python代码的大小有关.我已将它转换为迭代器,以便在您的闲暇时使用并打印以进行演示,但如果您所做的只是打印,则可以使用forEach(System.out :: println)而不是iterator()结束流序列.
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());
}
}
}
Run Code Online (Sandbox Code Playgroud)
我正在撰写有关生成器的实现,作为我的博客,关于Java 8函数编程和Lambda表达式的一部分,请访问http://thecannycoder.wordpress.com/,这可能会为您提供更多关于将Python生成器函数转换为Java等价物的想法.
小智 6
我希望Java有生成器/产量,但因为它不使用迭代器可能是你最好的选择.
在这个例子中我坚持使用数组,但一般来说我会建议使用Iterable Collection,例如.名单.在示例中,我展示了如何为数组获取迭代器非常容易:
package example.stackoverflow;
import com.sun.xml.internal.xsom.impl.scd.Iterators;
import java.util.Arrays;
import java.util.Iterator;
public class ArrayGenerator<T> implements Iterable<T> {
private final T[][][] input;
public ArrayGenerator(T[][][] input) {
this.input = input;
}
@Override
public Iterator<T> iterator() {
return new Iter();
}
private class Iter implements Iterator<T> {
private Iterator<T[][]> x;
private Iterator<T[]> y;
private Iterator<T> z;
{
x = Arrays.asList(input).iterator();
y = Iterators.empty();
z = Iterators.empty();
}
@Override
public boolean hasNext() {
return z.hasNext() || y.hasNext() || x.hasNext();
}
@Override
public T next() {
while(! z.hasNext()) {
while(! y.hasNext()) {
y = Arrays.asList(x.next()).iterator();
}
z = Arrays.asList(y.next()).iterator();
}
return z.next();
}
@Override
public void remove() {
throw new UnsupportedOperationException("remove not supported");
}
}
public static void main(String[] args) {
for(Integer i :
new ArrayGenerator<Integer>(
new Integer[][][]{
{
{1, 2, 3},
{4, 5}
},
{
{},
{6}
},
{
},
{
{7, 8, 9, 10, 11}
}
}
)) {
System.out.print(i + ", ");
}
}
}
Run Code Online (Sandbox Code Playgroud)
Java 中没有 yield,所以你必须自己做所有这些事情,最终得到这样一个荒谬的代码:
for(Integer z : new Iterable<Integer>() {
@Override
public Iterator<Integer> iterator() {
return new Iterator<Integer>() {
final Integer[][][] d3 =
{ { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } },
{ { 10, 11, 12 }, { 13, 14, 15 }, { 16, 17, 18 } },
{ { 19, 20, 21 }, { 22, 23, 24 }, { 25, 26, 27 } } };
int x = 0;
int y = 0;
int z = 0;
@Override
public boolean hasNext() {
return !(x==3 && y == 3 && z == 3);
}
@Override
public Integer next() {
Integer result = d3[z][y][x];
if (++x == 3) {
x = 0;
if (++y == 3) {
y = 0;
++z;
}
}
return result;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
}) {
System.out.println(z);
}
Run Code Online (Sandbox Code Playgroud)
但是如果你的样本有不止一个yield,结果会更糟。