How can I get an int[] out of an Iterator?

I have what amounts to an Iterator<Integer>… actually it’s a class Thing that accepts a Visitor<SomeObject> and calls visit() for a subset of the SomeObjects it contains, and I have to implement Visitor<SomeObject> so it does something like this:

// somehow get all the Id's from each of the SomeObject that Thing lets me visit
public int[] myIdExtractor(Thing thing)
{
    SomeCollection c = new SomeCollection();
    thing.visitObjects(new Visitor<SomeObject>()
         {
              public void visit(SomeObject obj) { c.add(obj.getId()); }
         }
    );
    return convertToPrimitiveArray(c);
}

I need to extract an int[] containing the results, and I’m not sure what to use for SomeCollection and convertToPrimitiveArray. The number of results is unknown ahead of time and will be large (10K-500K). Is there anything that would be a better choice than using ArrayList<Integer> for SomeCollection, and this:

public int[] convertToPrimitiveArray(List<Integer> ints)
{
    int N = ints.size();
    int[] array = new int[N];
    int j = 0;
    for (Integer i : ints)
    {
        array[j++] = i;
    }
    return array;
}

Efficiency and memory usage are of some concern.

Answer

It’s not too difficult to come up with a class that collects ints in an array (even if you are not using some library which does it for you).

public class IntBuffer {
    private int[] values = new int[10];
    private int size = 0;
    public void add(int value) {
        if (!(size < values.length)) {
            values = java.util.Arrays.copyOf(values, values.length*2);
        }
        values[size++] = value;
    }
    public int[] toArray() {
        return java.util.Arrays.copyOf(values, size);
    }
}

(Disclaimer: This is stackoverflow, I have not even attempted to compile this code.)

As an alternative you could use DataOutputStream to store the ints in a ByteArrayOutputStream.

final ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
final DataOutputStream out = new DataOutputStream(byteOut);
...
    out.writeInt(value);
...
out.flush();
final byte[] bytes = byteOut.toByteArray();
final int[] ints = new int[bytes.length/4];
final ByteArrayInputStream byteIn = new ByteArrayInputStream(bytes);
final DataInputStream in = new DataOutputStream(byteIn);
for (int ct=0; ct<ints.length; ++ct) {
    ints[ct] = in.readInt();
}

(Disclaimer: This is stackoverflow, I have not even attempted to compile this code.)

Leave a Reply

Your email address will not be published. Required fields are marked *