简体   繁体   中英

Adding elements of an Array to an ArrayList

I have a very small threaded application, which is collecting small chunks of data in arrays (because it is sound data, and Java wants that to be an array) and trying to put it into an ArrayList for storage. All of that is effectively the front half of a producer/consumer pattern.

Problem: It doesn't seem to work.

On the producer end, I have this code:

  public synchronized void run() {
// do a whole bunch of audio set-up

try {
  // more audio stuff

  while (true) {
    if (producing) {
      byte[] data = new byte[line.getBufferSize() ];
      numBytesRead = line.read(data, 0, data.length);
      System.out.println("Producer:  Size of dat[] is " + data.length);

      // Save this chunk of data.
      buffer.addData(data);
    }

This seems straightforward, aside from the audio stuff and bookkeeping.
In the buffer class, I have:

public class Buffer {
  ArrayList list ;
  public void addData(byte[] data) {
    list.addAll(Arrays.asList(data));
  }

This also seems straightforward. Here is the problem: If my array is of length (say) 1024, and the elements are all there (which I've verified that they are) I would expect the size of the ArrayList to grow by 1024 every time I add data. It doesn't. It grows by 1, as though I was making either an ArrayList of ArrayLists or an ArrayList of Arrays, rather than the Arraylist of elements I desire.

I suspect I'm going to have this problem on the flip side as well, where I might have an ArrayList of tens of thousands of bytes, and want to retrieve an array of the first 1024 elements.

I cannot help but think I'm missing something very simple. Can anyone shed light on why this is not working? (Or if there is some fundamentally better way to do what I'm trying to do?)

Arrays.asList() will not perform the conversion from byte to Byte , it will return a list containing 1 element; the byte[] you pass in.

If your aim is to add Byte objects for every byte, you will have to do that yourself in a loop. Note that this will use much more memory than passing byte[] s however.

Also note that it is not garuanteed that, even if the input stream has more than enough data left, that you will read data.length bytes every time (result of buffer sizes, concurency, etc.) so you run the risk of passing a bunch of 0 bytes at the end of your buffer if you read less bytes than you asked for.

byte[] data should be Byte[]. You must use object, not primitive.

I cannot help but think I'm missing something very simple. Can anyone shed light on why this is not working? (Or if there is some fundamentally better way to do what I'm trying to do?)

Storing byte data in an ArrayList<Byte> has a lot of memory overhead, compared to a byte[] array. if you're working with a large amount of data, you may want to use a byte[] array for storage as well. Take a look at the source code for ByteArrayOutputStream - I don't know if will work for you as-is, but you might be able to create a similar sort of class that manages an expanding byte array.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM