Итератор 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++];
}