简体   繁体   English

原始类型的Java迭代器

[英]Java Iterator for primitive types

I have a Java class of the following form: 我有一个以下形式的Java类:

class Example {

  private byte[][] data;

  public Example(int s) { data = new byte[s][s]; }

  public byte getter(int x, int y)         { return byte[x][y]; }
  public void setter(int x, int y, byte z) { byte[x][y] = z;    }
}

I would like to be able to externally iterate over the private data using an iterator like so: 我希望能够使用像这样的迭代器外部迭代私有数据:

for(byte b : Example) { ;/* do stuff */ }

I tried to implement a private Iterator class but I ran into problems: 我试图实现一个私有的Iterator类,但我遇到了问题:

private class ExampleIterator implements Iterator {
  private int curr_x;
  private int curr_y;

  public ExampleIterator() { curr_x=0; curr_y=-1; }
  public boolean hasNext() { 
    return curr_x != field.length-1
        && curr_y != field.length-1; //is not the last cell?
  }
  public byte next() { // <-- Error is here: 
                       // Wants to change return type to Object
                       // Won't compile!
    if(curr_y=field.length) { ++curr_x; curr_y=0; }
    return field[curr_x][curr_y];
  }
  public void remove() { ; } //does nothing
}

How would I implement an external iterator for primitive types (not generics)? 我如何为原始类型(非泛型)实现外部迭代器? Is this possible in Java? 这在Java中可行吗?

An iterator cannot yield values of a primitive type. 迭代器不能产生基本类型的值。 However, it could yield values of the wrapper type Byte . 但是,它可以产生包装类型Byte值。 Such values can be auto-unboxed into byte (as long as they are not null ). 这些值可以自动取消装入byte (只要它们不为null )。

private class ExampleIterator implements Iterator<Byte> {
  public boolean hasNext() { ... }
  public Byte next() { ... }
}

Then you can use it like so: 然后你可以像这样使用它:

for (byte b : example) { ... }

Java 8 introduced primitive iterators , that allow you to avoid boxing/unboxing during iteration over int, long and double collections. Java 8引入了原始迭代器 ,允许您在int,long和double集合的迭代期间避免装箱/取消装箱。

You can create you own PrimitiveIterator of byte with typesafely implementing generic PrimitiveIterator<Byte,ByteConsumer> . 你可以创建自己的PrimitiveIteratorbyte与typesafely实现通用PrimitiveIterator<Byte,ByteConsumer> ByteConsumer is also to be implemented. ByteConsumer也将实施。 Both are pretty straightforward. 两者都非常简单。

Why is there no PrimitiveIterator.ofByte in jdk? 为什么jdk中没有PrimitiveIterator.ofByte Probably because of machine word size, that is usually not smaller than int. 可能是因为机器字大小,通常不小于int。 Or byte iterators are better done by streams and such. 或者字节迭代器最好由流等完成。

You can't use generics with primitives, as the generics require a class for the type. 您不能将泛型与基元一起使用,因为泛型需要类型的类。

What you can do is iterate over the Wrapper types (Integer, Byte, Boolean, etc)... 你可以做的是迭代Wrapper类型(整数,字节,布尔等)......

Implement Iterable , and return a Byte object instead of a byte primitive: 实现Iterable ,并返回Byte对象而不是byte基元:

class Example implements Iterable<Byte> {

..

    public Iterator<Byte> iterator() {
        return new MyIterator();
    }

    private class MyIterator implements Iterator<Byte> {
        public Byte next() {...}
        ....
    }
}

Implementing Iterable instead of Iterator allows you to loop on the object items directly, using the for-each loop. 实现Iterable而不是Iterator允许您使用for-each循环直接循环对象项。

If you want your iterator to implement java.util.Iterator then next() will have to return Byte 如果希望迭代器实现java.util.Iterator,则next()必须返回Byte

class ByteArrayIterator implements Iterator<Byte> {
    final byte[] a; 
    int i = 0;
    ByteArrayIterator(byte[] a) {
        this.a = a; 
    }

    public boolean hasNext() {
        return i < a.length;
    }

    public Byte next() {
        if (i == a.length) {
            throw new NoSuchElementException();
        }
        return a[i++];
    }

    public void remove() {
        throw new UnsupportedOperationException();
    }
}

remove can be implemented too. 删除也可以实现。 If you dont need it implemnent Iterator then we can change next() to return byte 如果你不需要它实现Iterator,那么我们可以改变next()来返回字节

    class ByteArrayIterator {
...
    public byte next() {
            if (i == a.length) {
                throw new NoSuchElementException();
            }
            return a[i++];
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM