2013-04-03 106 views
8

我有一個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中引入的primitive iterators,這讓你避免遍歷所有的int,long和double集合時裝箱/拆箱。

您可以創建自己的PrimitiveIterator of byte,其中可以使用類型來實現通用的PrimitiveIterator<Byte,ByteConsumer>ByteConsumer也是要實施的。兩者都很簡單。

爲什麼jdk中沒有PrimitiveIterator.ofByte?可能是因爲機器字的大小,通常不會小於int。或者字節迭代器最好由流等來完成。

+0

是否有一個用於原始類型的模擬'Iterable',所以我可以做'for(double d:myContainerWithDoubles){}'? –

+0

沒有for-each原型迭代器。最佳匹配是實現'PrimitiveIterator.OfDouble'並以功能性的方式使用它。 – Oroboros102

8

迭代器不能產生基元類型的值。但是,它可能會產生包裝類型Byte的值。這些值可以是auto-unboxedbyte(只要它們不是null)。

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

然後你可以使用它像這樣:

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

我不熟悉自動(聯合)拳擊的概念。這是我的困惑源於哪裏以及解決方案的發現地點。 –

+0

@awashburn:參見http://docs.oracle.com/javase/tutorial/java/data/autoboxing.html – NPE

+2

這樣的正常自動裝箱方式可以快速生成大量垃圾。然而,對於'Byte',我相信大多數Java實現使用flyweight模式(因爲只有256個'byte'值),所以GC沒有額外的負擔。但是請注意,你必須使用'for(byte b:instanceOfExample)' - 你不能遍歷一個類。 –

0

實施Iterable,並返回,而不是一個字節的原始一個字節對象:

class Example implements Iterable<Byte> { 

.. 

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

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

實施可迭代,而不是迭代器可以讓你使用for-each循環直接在對象項上循環。

1

您不能將泛型與基元一起使用,因爲泛型需要類型的類。

0

如果你想你可以做的是遍歷包裝類型(整數,字節,布爾等)......你的迭代器實現了java.util.Iterator然後單擊Next()將返回字節

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(); 
    } 
} 

刪除也可以實現。如果你不需要它implemnent迭代器,然後我們可以改變未來()返回字節

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