有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java重复数组列表项

我目前正在组装一个小的客户机/服务器对,我遇到了ArrayList的一个问题,我解决了这个问题,但我想了解更多。下面是代码示例:

public double[] receiveMessage(int messageLength) throws IOException {
    // wait for bytes
    while (this.getInputStream().available() == 0) {
    }

    // read bytes
    List<byte[]> incomingMessage = new ArrayList<byte[]>();

    int byteLength = 8;
    byte[] tempByte = new byte[byteLength];
    while (this.getInputStream().available() != 0) {
        this.getInputStream().read(tempByte, 0, byteLength);
        incomingMessage.add(tempByte);
    } ............

如果在每次循环迭代时打印tempByte,我将收到预期的唯一数组。但是,如果我要打印完整列表“incomingMessage”的每个元素,我会收到相同的数组(最后一个tempByte数组)“messageLength”次

当我将tempByte声明放在while循环中,并在将其添加到列表后添加tempByte=null时,这个错误得到了修复

虽然我不是编程专家,但我看到的最初bug的原因是什么


共 (3) 个答案

  1. # 1 楼答案

    问题在于:

    byte[] tempByte = new byte[byteLength];
    while (this.getInputStream().available() != 0) {
        //...
    }
    

    tempByte初始化一次并填充多次。最后,将存储在tempByte中的同一对象引用更改并存储到incomingMessage中,从而在List中多次看到相同的数组

    有两种可能的解决方案:

    1. 在尽可能窄的范围内初始化变量。在这种情况下,tempByte范围应该在while循环内:

      while (this.getInputStream().available() != 0) {
          //declare the variable here
          byte[] tempByte = new byte[byteLength];
          //...
      }
      
    2. while循环的每次迭代中重新初始化数组:

      byte[] tempByte = new byte[byteLength];
      while (this.getInputStream().available() != 0) {
          //...
          //reinitialize the variable
          tempByte = new byte[byteLength];
      }
      

    在我看来,您应该选择1而不是2来简化代码的可读性

  2. # 2 楼答案

    您多次将同一对象(tempByte数组)添加到incomingMesage列表中。在每次迭代中,您都会覆盖该数组的内容

    如果您想这样存储数据,您需要将tempByte复制到新数组中,并将其插入列表中

  3. # 3 楼答案

    您每次都在修改相同的byte[]对象。在while循环的每次迭代中替换数组的元素,然后调用read

    在数组中声明tempByte可以解决这个问题的原因是,您现在在每次迭代中都创建了一个新的、单独的字节数组。不再多次添加一个数组,而是添加了多个不同的数组