La maggior parte delle operazioni relative ai byte viene automaticamente promossa a int. Per esempio, consideriamo il metodo semplice che aggiunge una costante byte
ad ogni elemento della byte[]
matrice rinvio nuovo byte[]
array (potenziale candidato ByteStream
):
public static byte[] add(byte[] arr, byte addend) {
byte[] result = new byte[arr.length];
int i=0;
for(byte b : arr) {
result[i++] = (byte) (b+addend);
}
return result;
}
See, anche se eseguiamo un'aggiunta di due byte
variabili, sono ampliati a int
e devi restituire il risultato a byte
. Nel bytecode Java la maggior parte delle operazioni correlate a byte
(ad eccezione di caricamento/archiviazione dell'array e cast in byte) sono espresse con istruzioni integer a 32 bit (iadd
, ixor
, if_icmple
e così via). Pertanto, in pratica, è possibile elaborare byte come intersezioni con IntStream
. Dobbiamo solo due operazioni aggiuntive:
- creare un
IntStream
da byte[]
matrice (allargamento byte interi)
- Raccogliere un array
IntStream
a byte[]
(usando (byte)
getto)
Il primo è davvero facile e può essere implementato in questo modo:
public static IntStream intStream(byte[] array) {
return IntStream.range(0, array.length).map(idx -> array[idx]);
}
S o puoi aggiungere questo metodo statico al tuo progetto ed essere felice.
La raccolta dello stream nell'array byte[]
è più complessa.Utilizzo di classi JDK standard, la soluzione più semplice è ByteArrayOutputStream
:
public static byte[] toByteArray(IntStream stream) {
return stream.collect(ByteArrayOutputStream::new, (baos, i) -> baos.write((byte) i),
(baos1, baos2) -> baos1.write(baos2.toByteArray(), 0, baos2.size()))
.toByteArray();
}
Tuttavia ha inutile sovraccarico a causa di sincronizzazione. Inoltre sarebbe bello elaborare in modo speciale i flussi di lunghezza nota per ridurre le allocazioni e la copia. Tuttavia ora è possibile utilizzare l'API di flusso per byte[]
array:
public static byte[] addStream(byte[] arr, byte addend) {
return toByteArray(intStream(arr).map(b -> b+addend));
}
Biblioteca StreamEx ha entrambe queste operazioni nella classe IntStreamEx
che migliora standard di IntStream
, in modo da poter usare in questo modo:
public static byte[] addStreamEx(byte[] arr, byte addend) {
return IntStreamEx.of(arr).map(b -> b+addend).toByteArray();
}
Internamente il metodo toByteArray()
utilizza il semplice ridimensionabile byte buffer e specially handles il caso in cui lo streaming è sequenziale e la dimensione della destinazione è nota in anticipo.
http://stackoverflow.com/questions/22918847/why-are-new-java-util-arrays-methods-in-java-8-not-overloaded-for-all-the-primit – assylias