views:

544

answers:

7

Hello,

We use this small utility method. But we dont like it. Since it's not very crucial ( that work anyway ... ) , we have forget it. But that's ugly, because we have to go through the whole array, only to convert it from Byte[] to byte[]. I'm looking

  • for a way to cast the Byte [] in byte [] without go throu it
  • or for a utility method for cast a List into string

 

  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);
}
A: 

Check out the BitConverter class, I think it does what you want. Use it in combination with the List.toArray() method.

Colin
Why the downvote? It does exactly what you want???
Colin
This is a java question, not .net.
Kees de Kooter
It's pretty interesting though that the code looks exactly like C#. If it wasn't for the "Java" tag then there would be no way to tell. Perhaps we need a clearer way to indicate language in programming questions where there might be ambiguity.
Jon Grant
"for (Byte current : l)" <-- not C#
AakashM
Sorry, my bad.... Agree with Jon here though.
Colin
You can almost always tell the difference by looking at the s in string. string = c#, String = java. :)
Emil H
String would also work in .NET, it's the classname instead of the C# keyword.
Colin
+3  A: 
import org.apache.commons.lang.ArrayUtils;

...

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

byte[] b =  .toPrimitive(bytes);
Rich Seller
Isn't ArrayUtils part of apache commons?
Emil H
Yes it is, added the import, thanks
Rich Seller
I don't think this is much of an improvement - you are adding a dependency to a 3rd party library, which internally will probably do something similar to the above code anyway.
Jon
@Jon: I partially agree - I dislike adding third party dependencies just for the odd util. method but if this dependency exists already then I think it makes the code more succinct and readable.
Adamski
@Jon I too partially agree, but commons-lang is probably one of the safest third-party libraries to use, asd as Adamski says you'd probably end up using it more than once.
Rich Seller
+1  A: 

without any additional library (e.g. apache commons) your method is fine

dfa
A: 

One option might be to use 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();
}

Or, if you need character conversion

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

If you are aggregating bytes, try ByteArrayOutputStream in the first place instead of List of bytes. Note: Watch out for the UnsupportedEncodingException - you'll need to try-catch it somewhere.

kd304
+6  A: 

Your method is pretty much the only way to do it. You may find an external library that does all or part of it, but it will essentially do the same thing.

However, there is one thing in your code that is a potential problem: When calling new String(array), you are using the platform default encoding to convert the bytes to characters. The platform encoding differs between operating system and locale settings - using it is almost always a bug waiting to happen. It depends on where you're getting those bytes from, but their encoding should be specified somewhere, passed as argument to the method and used for the conversion (by using the String constructor with a second parameter).

Michael Borgwardt
+1 for pointing out the encoding problem
dfa
A: 

Minor nit:

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

to avoid creating empty Strings for empty lists.

Robert Munteanu
A: 

You could use java.nio and come up with something like this

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

but I really don't think I'd recommend for something this simple.

Ben Hammond