2009-07-08 8 views
5

Utilizamos este pequeño método de utilidad. Pero no nos gusta Como no es muy crucial (funciona de todos modos ...), lo hemos olvidado.
Pero eso es feo, porque tenemos que pasar por toda la matriz, solo para convertir de Byte[] a byte[].
Busco:Lista <Byte> a String, ¿puede ayudar a refactorizar este (pequeño) método?

  • una manera de emitir el Byte[] en byte[] sin tener que pasar a través de él
  • o para un método de utilidad para el elenco de una lista en la cadena de

public static String byteListToString(List<Byte> l, Charset charset) { 
    if (l == null) { 
     return ""; 
    } 
    byte[] array = new byte[l.size()]; 
    int i = 0; 
    for (Byte current : l) { 
     array[i] = current; 
     i++; 
    } 
    return new String(array, charset); 
} 
+2

Primero pensé ... ¿se refiere a métodos como 'ella'? – sisve

+0

¿por qué no ella? Las señoras son las lógicas –

+3

Asker es francés; El método francés es "la methode" (el francés es un idioma con género); la traducción natural al inglés produce 'ella'. Creo que es divertido :) Si los automóviles y los barcos pueden ser tradicionalmente mujeres, ¿por qué no métodos? – AakashM

Respuesta

8

Su método es prácticamente la única forma de hacerlo. Puede encontrar una biblioteca externa que haga todo o parte de ella, pero esencialmente hará lo mismo.

Sin embargo, hay una cosa en su código que es un problema potencial: Al llamar al new String(array), está utilizando la codificación predeterminada de la plataforma para convertir los bytes en caracteres. La codificación de la plataforma difiere entre la configuración del sistema operativo y la configuración regional; usarla casi siempre es un error que está por ocurrir. Depende de dónde obtengas esos bytes, pero su codificación debe especificarse en alguna parte, pasar como argumento al método y usarse para la conversión (usando el constructor de cadenas con un segundo parámetro).

+0

+1 para señalar el problema de codificación – dfa

-2

Echa un vistazo a BitConverter clase, creo que hace lo que quieres. Úselo en combinación con el método List.toArray().

+0

¿Por qué el voto a favor? ¿Hace exactamente lo que quieres? – Colin

+1

Esta es una pregunta de Java, no .net. –

+0

Aunque es bastante interesante que el código se vea exactamente como C#. Si no fuera por la etiqueta "Java", entonces no habría forma de saberlo. Tal vez necesitamos una manera más clara de indicar el lenguaje en las preguntas de programación donde podría haber ambigüedad. –

3
import org.apache.commons.lang.ArrayUtils; 

... 

Byte[] bytes = new Byte[l.size()]; 
l.toArray(bytes); 

byte[] b = ArrayUtils.toPrimitive(bytes); 
+1

No creo que esto sea una gran mejora: está agregando una dependencia a una biblioteca de terceros, que internamente probablemente haga algo similar al código anterior de todos modos. – Jon

+0

@Jon: estoy parcialmente de acuerdo: no me gusta agregar dependencias de terceros solo para la utilidad impar. método, pero si esta dependencia ya existe, entonces creo que hace que el código sea más breve y legible. – Adamski

+0

@Jon Yo también estoy parcialmente de acuerdo, pero Commons-lang es probablemente una de las librerías de terceros más seguras, así como Adamski dice que probablemente termines usándola más de una vez. –

1

sin ninguna librería adicional (por ejemplo Apache Commons) el método es bien

-1

Una opción podría ser el uso de StringBuilder:

public static String byteListToString(List<Byte> l) { 
    if (l == null) { 
     return "" ; 
    } 
    StringBuilder sb = new StringBuilder(l.size()); 

    for (Byte current : l) { 
     sb.append((char)current); 
    } 

    return sb.toString(); 
} 

O, si necesita la conversión de caracteres

public static String byteListToString(List<Byte> l) { 
    if (l == null) { 
     return "" ; 
    } 
    ByteArrayOutputStream bout = new ByteArrayOutputStream(l.size()); 

    for (Byte current : l) { 
     bout.write(current); 
    } 

    return bout.toString("UTF-8"); 
} 

Si está agregando bytes, pruebe ByteArrayOutputStream en primer lugar en lugar de List of byte s. Nota: Tenga cuidado con UnsupportedEncodingException; deberá intentar atraparlo en algún lugar.

+0

Ambos fragmentos son mucho más lentos y la memoria ineficiente, en comparación con el publicado por OP. –

1

nit Menor:

if (l == null || l.isEmpty()) { 
    return "" ; 
} 

para evitar la creación de cadenas vacías para las listas vacías.

0

Usted podría utilizar java.nio y llegar a algo como esto

public static String byteListToString(List<Byte> l, Charset cs) 
throws IOException 
{ 
    final int CBUF_SIZE = 8; 
    final int BBUF_SIZE = 8; 

    CharBuffer cbuf = CharBuffer.allocate(CBUF_SIZE); 
    char[] chArr = cbuf.array(); 
    ByteBuffer bbuf = ByteBuffer.allocate(BBUF_SIZE); 
    CharsetDecoder dec = cs.newDecoder(); 
    StringWriter sw = new StringWriter((int)(l.size() * dec.averageCharsPerByte())); 

    Iterator<Byte> itInput = l.iterator(); 
    int bytesRemaining = l.size(); 
    boolean finished = false; 
    while (! finished) 
    { 
     // work out how much data we are likely to be able to read 
     final int bPos = bbuf.position(); 
     final int bLim = bbuf.limit(); 
     int bSize = bLim-bPos; 
     bSize = Math.min(bSize, bytesRemaining); 
     while ((--bSize >= 0) && itInput.hasNext()) 
     { 
      bbuf.put(itInput.next().byteValue()); 
      --bytesRemaining; 
     } 
     bbuf.flip(); 
     final int cStartPos = cbuf.position(); 
     CoderResult cr = dec.decode(bbuf, cbuf, (bytesRemaining <= 0)); 
     if (cr.isError()) cr.throwException(); 
     bbuf.compact(); 
     finished = (bytesRemaining <= 0) && (cr == CoderResult.UNDERFLOW); 
     final int cEndPos = cbuf.position(); 
     final int cSize = cEndPos - cStartPos; 
     sw.write(chArr, cStartPos, cSize); 
     cbuf.clear(); 
    } 
    return sw.toString(); 
} 

pero realmente no creo que recomiendo para algo tan simple.

1

Guava proporciona una serie de útil primitive utilities, incluyendo una clase Bytes que hace que esta y otras operaciones en colecciones de Byte s trivial.

private static String toString(List<Byte> bytes) { 
    return new String(Bytes.toArray(bytes), StandardCharsets.UTF_8); 
} 
Cuestiones relacionadas