Java 列表<;字节>;对于字符串,您能帮助重构这个(小)方法吗?

Java 列表<;字节>;对于字符串,您能帮助重构这个(小)方法吗?,java,arrays,bytearray,Java,Arrays,Bytearray,我们使用这个小实用方法。但我们不喜欢它。因为它不是很关键(不管怎样,它还是有效的…),我们已经忘记了它。 但这很难看,因为我们必须遍历整个数组,然后才能转换 它从字节[]到字节[] 我在看: 有关在Byte[]中强制转换Byte[]的方法,请参见 或用于将列表强制转换为字符串的实用方法 公共静态字符串byteListToString(列表l,字符集){ if(l==null){ 返回“”; } 字节[]数组=新字节[l.size()]; int i=0; 用于(当前字节:l){ 数组[i]

我们使用这个小实用方法。但我们不喜欢它。因为它不是很关键(不管怎样,它还是有效的…),我们已经忘记了它。
但这很难看,因为我们必须遍历整个数组,然后才能转换 它从
字节[]
字节[]

我在看:

  • 有关在
    Byte[]
    中强制转换
    Byte[]
    的方法,请参见
  • 或用于将列表强制转换为字符串的实用方法

公共静态字符串byteListToString(列表l,字符集){
if(l==null){
返回“”;
}
字节[]数组=新字节[l.size()];
int i=0;
用于(当前字节:l){
数组[i]=当前值;
i++;
}
返回新字符串(数组、字符集);
}

看看这门课,我想它能满足你的需要。将其与List.toArray()方法结合使用。

无需任何附加库(例如apache commons),您的方法很好

一个选项可能是使用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();
}
公共静态字符串byteListToString(列表l){
if(l==null){
返回“”;
}
StringBuilder sb=新的StringBuilder(l.size());
用于(当前字节:l){
sb.追加((字符)当前值);
}
使某人返回字符串();
}
或者,如果需要字符转换

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");
}
公共静态字符串byteListToString(列表l){
if(l==null){
返回“”;
}
ByteArrayOutputStream bout=新的ByteArrayOutputStream(l.size());
用于(当前字节:l){
写(当前);
}
返回回合toString(“UTF-8”);
}

如果要聚合字节,请首先尝试ByteArrayOutputStream,而不是字节列表。注意:注意不支持的编码异常-您需要在某个地方尝试捕获它。

您的方法几乎是唯一的方法。您可能会发现一个外部库完成了它的全部或部分工作,但它基本上会完成相同的工作

但是,代码中有一个潜在问题:调用
新字符串(数组)
时,使用平台默认编码将字节转换为字符。平台编码在操作系统和区域设置之间是不同的——使用它几乎总是一个等待发生的错误。这取决于从何处获取这些字节,但它们的编码应该在某处指定,作为参数传递给方法并用于转换(通过使用带第二个参数的字符串构造函数)。

次要nit:

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

为了避免为空列表创建空字符串。

您可以使用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();
}
公共静态字符串byteListToString(列表l,字符集cs)
抛出IOException
{
最终int CBUF_尺寸=8;
最终int BBUF_尺寸=8;
CharBuffer cbuf=CharBuffer.allocate(cbuf_大小);
char[]chArr=cbuf.array();
ByteBuffer bbuf=ByteBuffer.allocate(bbuf_大小);
CharsetDecoder dec=cs.newDecoder();
StringWriter sw=新的StringWriter((int)(l.size()*dec.averageCharsPerByte());
迭代器itInput=l.Iterator();
int byteslaining=l.size();
布尔完成=假;
当(!完成)
{
//计算出我们能够读取多少数据
final int bPos=bbuf.position();
final int bLim=bbuf.limit();
int bSize=bLim BPO;
bSize=Math.min(bSize,字节剩余);
而((-bSize>=0)和&itInput.hasNext()
{
bbuf.put(itInput.next().byteValue());
--字节剩余;
}
bbuf.flip();
最终int cStartPos=cbuf.position();
CoderResult cr=dec.decode(bbuf,cbuf,(byteslaining提供了许多有用的函数,包括一个类,该类使得对
字节的集合执行此操作和其他操作变得微不足道

private static String toString(List<Byte> bytes) {
  return new String(Bytes.toArray(bytes), StandardCharsets.UTF_8);
}
私有静态字符串到字符串(列表字节){
返回新字符串(Bytes.toArray(Bytes),StandardCharsets.UTF_8);
}

这是一个java问题,而不是.net。虽然代码看起来与C#一模一样,但这很有趣。如果不是“java”标记,那么就没有办法知道了。也许我们需要一种更清晰的方式来指出编程问题中可能存在歧义的语言。“for(Byte current:l)”通过查看string.string=c#,string=java.:)中的s,几乎总能看出区别字符串也可以在.NET中使用,它是类名而不是C#关键字。我不认为这是一个很大的改进-您正在向第三方库添加依赖项,这在内部可能会执行类似于上述代码的操作。@Jon:我部分同意-我不喜欢只为奇怪的util.methodo添加第三方依赖项d但如果这种依赖关系已经存在,那么我认为它会使代码更加简洁易读。@Jon我也部分同意,但commons lang可能是使用最安全的第三方库之一,正如Adamski所说,asd最终可能会不止一次地使用它。首先,我想……你是否将方法称为“她”呢?为什么不是她?女士们是合乎逻辑的onesAsker是法语;methode是法语(法语是一种有性别的语言);自然翻译成英语会产生“她”。我觉得很有趣:)如果汽车和轮船传统上都是女性,为什么不使用方法呢?Java中没有优雅的方法可以将一个数组作为一个整体取消装箱。我们还没有测试过这一点,但这是否有效:新字符串(l.toArray(新字节[0]);?与OP发布的代码相比,这两个代码段都要慢得多,内存效率也低得多。
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();
}
private static String toString(List<Byte> bytes) {
  return new String(Bytes.toArray(bytes), StandardCharsets.UTF_8);
}