Итератор Java для примитивных типов

у меня есть класс 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;    }
}

Я хотел бы иметь возможность внешне перебирать частные данные, используя итератор, например:

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

Я попытался реализовать частный класс итератора, но столкнулся с проблемами:

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
}

как бы я реализовал внешний итератор для примитивных типов (не дженерики)? Возможно ли это на Java?

5 ответов


Java 8 введен примитивный итераторы, что позволяет избежать бокса / распаковки во время итерации по int, long и double коллекциям.

вы можете создать собственный PrimitiveIterator of byte С typesafely реализации generic PrimitiveIterator<Byte,ByteConsumer>. ByteConsumer также должно быть реализовано. Оба довольно просты.

почему нет PrimitiveIterator.ofByte в jdk? Вероятно, из-за размера машинного слова, который обычно не меньше int. Или лучше сделать байтовые итераторы потоки и таким.


итератор не может выдавать значения примитивного типа. Однако он может давать значения типа оболочки Byte. Такие значения могут быть авто-без коробки на byte (пока они не null).

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

тогда вы можете использовать его так:

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

вы не можете использовать дженерики с примитивами, так как дженерики требуют класс для типа.

Что вы можете сделать, это перебирать типы обертки (Integer, Byte, Boolean и т. д.)...


реализовать типа Iterable и возвращает объект Byte вместо примитива byte:

class Example implements Iterable<Byte> {

..

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

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

реализация Iterable вместо Iterator позволяет выполнять цикл непосредственно на элементах объекта, используя цикл for-each.


Если вы хотите, чтобы ваш итератор реализовал java.утиль.Итератор затем 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 также может быть реализован. Если вам не нужен имплемнентный итератор, мы можем изменить next (), чтобы вернуть byte

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