2016-04-27 78 views
3

我想InputStream一個字節序列:0,1,2,... 255短,聰明的方法來創建從字節序列InputStream

我當然可以創建一個new byte[0x100],創造int一個循環,以轉換爲byteint值填充它(不要讓我開始對Java的簽署byte型),然後從形成一個ByteArrayInputStream

但是,使用Java 8肯定會有更好,更緊湊,更聰明的方式。技巧似乎在生成字節數組。我發現elsewhereint這是因爲以下簡單:

final int[] values = IntStream.range(0, 0x100).toArray(); 

但我需要一個byte陣列,並沒有ByteStream。也許有一個IntStream收集函數可以將int值收集到byte[]數組中?或者更聰明的東西?

+0

你能說清楚你是從一個InputStream還是一個字節序列開始的?你的問題暗示了兩者。源或期望的字節序列採取什麼形式?例如,它是一個字節[],還是一個流或其他東西? –

+0

產生特定序列的'InputStream'是我想要_end_開始的地方。一個'byte []'似乎是一個明顯的方法,但如果你有一個更直接的技巧來創建一個'InputStream',就可以跳過字節數組。 –

+0

你的字節序列採用什麼形式?它是特定的序列{1,2,...,255}嗎?或者它是某種類型的任意字節的容器? –

回答

1

您可以聲明byte[],然後使用IntStreamforEach來填充它。像

byte[] arr = new byte[256]; 
IntStream.range(0, arr.length).forEach(x -> arr[x] = (byte) x); 
0

東西循環速度會更快,但如果你要求的討論,你會如何與流解決了的緣故吧,你能做到這一點,從番石榴Bytes API一點幫助:

byte[] bytes = IntStream.range(0, 0x100) 
    .mapToObj(i -> (byte) i)      // boxes into a Byte 
    .collect(Collectors.collectingAndThen(Collectors.toList(), Bytes::toArray)) 

在這個例子中,每個int都包裝在一個Byte中,這些Byte被收集到一個List中,然後轉換爲byte []。

這種方法的優點是它在預先不知道目標數組大小的情況下工作。如果你知道數組的大小,@ElliotFrisch的答案會更有效率,而且循環效率更高。

0

這太糟糕了,沒有Arrays.setAll的字節版本。它會像這樣工作:

byte[] foo = new byte[0x100]; 
setAll(foo, i -> i++); 

如果有人真的想要它雖然,他們可以利用這一點,改編自int版本的Arrays.setAll

public static void setAll(byte[] array, IntUnaryOperator generator) { 
    Objects.requireNonNull(generator); 
    for (int i = 0; i < array.length; i++) 
     array[i] = (byte)generator.applyAsInt(i); 
} 
0

如果你想創建一個懶InputStreamIntStream(僅使用至少顯著字節),你可以試試這個:

public static InputStream asByteInputStream(IntStream is) { 
    Spliterator.OfInt spltr = is.spliterator(); 
    return new InputStream() { 
     private int last; 

     @Override 
     public int read() { 
      return spltr.tryAdvance((int val) -> last = val) ? (last & 0xFF) : -1; 
     } 

     @Override 
     public void close() { 
      is.close(); 
     } 
    }; 
} 

使用測試:

AtomicBoolean flag = new AtomicBoolean(false); 
InputStream is = asByteInputStream(IntStream.range(0, 256).onClose(() -> flag.set(true))); 
byte[] data = new byte[256]; 
assertEquals(2, is.skip(2)); 
// read 3..255 into data[0..253] 
assertEquals(254, is.read(data)); 
// nothing more in the input 
assertEquals(-1, is.read()); 
for(int i=0; i<254; i++) { 
    assertEquals((byte)(i+2), data[i]); 
} 
assertEquals(0, data[254]); 
assertEquals(0, data[255]); 

// close is forwarded to original IntStream 
assertFalse(flag.get()); 
is.close(); 
assertTrue(flag.get());