2009-07-08 2 views
5

Мы используем этот небольшой метод утилиты. Но нам это не нравится. Поскольку это не очень важно (все равно работает), мы забыли его.
Но это уродливо, потому что нам нужно пройти весь массив, только для преобразования от Byte[] до byte[].
Я ищу:Список <Byte> Строка, вы можете помочь реорганизовать этот (маленький) метод?

  • способа бросить Byte[] в byte[] без прохождения через него
  • или метод полезности для гипса Списка в строку

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

Первая мысль ... вы ссылаетесь на методы как на «она»? – sisve

+0

почему бы и нет? Дамы являются логическими –

+3

Asker is French; Французский для метода «la methode» (французский язык является языком с полом); естественный перевод на английский язык производит «она». Я думаю, что это забавно :) Если автомобили и корабли традиционно могут быть женщинами, почему бы и нет методов? – AakashM

ответ

8

Ваш метод - это единственный способ сделать это. Вы можете найти внешнюю библиотеку, которая делает все или часть ее, но она будет по сути делать то же самое.

Однако в вашем коде есть одна вещь, которая является потенциальной проблемой: при вызове new String(array) вы используете кодировку по умолчанию платформы для преобразования байтов в символы. Кодировка платформы отличается от операционной системы и настроек локали - использование почти всегда является ошибкой, ожидающей своего появления. Это зависит от того, откуда вы берете эти байты, но их кодирование должно быть где-то указано, передано в качестве аргумента для метода и использовано для преобразования (с помощью конструктора String со вторым параметром).

+0

+1 для указания проблемы кодирования – dfa

-2

Отъезд BitConverter класс, я думаю, он делает то, что вы хотите. Используйте его в сочетании с методом List.toArray().

+0

Почему downvote? Он делает именно то, что вы хотите ??? – Colin

+1

Это вопрос Java, а не .net. –

+0

Это довольно интересно, хотя код выглядит точно так же, как C#. Если бы не тег «Java», тогда не было бы возможности сказать. Возможно, нам нужен более четкий способ указать язык в вопросах программирования, где может быть двусмысленность. –

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

... 

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

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

Я не думаю, что это большое улучшение - вы добавляете зависимость от сторонней библиотеки, которая, в любом случае, будет делать что-то похожее на вышеуказанный код. – Jon

+0

@Jon: Я частично согласен - мне не нравятся добавления сторонних зависимостей только для нечетного использования. но если эта зависимость уже существует, я думаю, что она делает код более кратким и читаемым. – Adamski

+0

@ Я слишком частично согласен, но commons-lang, вероятно, является одной из самых безопасных сторонних библиотек для использования, asd, так как Adamski говорит, что вы, вероятно, в конечном итоге используете его более одного раза. –

1

без какой-либо дополнительной библиотеки (например, Apache Commons) ваш метод отлично

-1

Одним из вариантов может быть использование 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(); 
} 

Или, если вам нужно преобразование символов

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

Если вы агрегируете байты, попробуйте ByteArrayOutputStream в первую очередь вместо списка байтов s. Примечание. Следите за UnsupportedEncodingException - вам нужно попытаться найти его где-нибудь.

+0

Оба фрагмента намного медленнее, а память неэффективна, по сравнению с тем, который был отправлен OP. –

1

Малой нит:

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

, чтобы избежать создания пустых строк для пустых списков.

0

Вы можете использовать java.nio и придумать что-то вроде этого

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

, но я действительно не думаю, что я бы рекомендовал что-то это просто.

1

Guava предоставляет ряд полезных primitive utilities, в том числе Bytes класса, который делает это и другие операции над коллекциями Byte тривиально.

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

 Смежные вопросы

  • Нет связанных вопросов^_^