How can I convert int[] to Integer[] in Java?

Viewed 244850

I'm new to Java and very confused.

I have a large dataset of length 4 int[] and I want to count the number of times that each particular combination of 4 integers occurs. This is very similar to counting word frequencies in a document.

I want to create a Map<int[], double> that maps each int[] to a running count as the list is iterated over, but Map doesn't take primitive types.

So I made Map<Integer[], Double>.

My data is stored as an ArrayList<int[]>, so my loop should be something like:

ArrayList<int[]> data = ... // load a dataset`

Map<Integer[], Double> frequencies = new HashMap<Integer[], Double>();

for(int[] q : data) {

    // **DO SOMETHING TO convert q from int[] to Integer[] so I can put it in the map

    if(frequencies.containsKey(q)) {
    frequencies.put(q, tfs.get(q) + p);
    } else {
        frequencies.put(q, p);
    }
}

I'm not sure what code I need at the comment to make this work to convert an int[] to an Integer[]. Or maybe I'm fundamentally confused about the right way to do this.

12 Answers

If you want to convert an int[] to an Integer[], there isn't an automated way to do it in the JDK. However, you can do something like this:

int[] oldArray;

... // Here you would assign and fill oldArray

Integer[] newArray = new Integer[oldArray.length];
int i = 0;
for (int value : oldArray) {
    newArray[i++] = Integer.valueOf(value);
}

If you have access to the Apache lang library, then you can use the ArrayUtils.toObject(int[]) method like this:

Integer[] newArray = ArrayUtils.toObject(oldArray);

Convert int[] to Integer[]:

    import java.util.Arrays;
    ...

    int[] aint = {1,2,3,4,5,6,7,8,9,10};
    Integer[] aInt = new Integer[aint.length];

    Arrays.setAll(aInt, i -> aint[i]);

Presumably you want the key to the map to match on the value of the elements instead of the identity of the array. In that case you want some kind of object that defines equals and hashCode as you would expect. Easiest is to convert to a List<Integer>, either an ArrayList or better use Arrays.asList. Better than that you can introduce a class that represents the data (similar to java.awt.Rectangle but I recommend making the variables private final, and the class final too).

The proper solution is to use this class as a key in the map wrapping the actual int[].

public class IntArrayWrapper {
    int[] data;

    public IntArrayWrapper(int[] data) {
        this.data = data;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o)
            return true;
        if (o == null || getClass() != o.getClass())
            return false;

        IntArrayWrapper that = (IntArrayWrapper) o;

        if (!Arrays.equals(data, that.data))
            return false;

        return true;
    }

    @Override
    public int hashCode() {
        return data != null ? Arrays.hashCode(data) : 0;
    }
}

And change your code like this:

Map<IntArrayWrapper, Double > freqs = new HashMap<IntArrayWrapper, Double>();

for (int[] data : datas) {
    IntArrayWrapper wrapper = new IntArrayWrapper(data);

    if (freqs.containsKey(wrapper)) {
        freqs.put(wrapper, freqs.get(wrapper) + p);
    }

    freqs.put(wrapper, p);
}

Rather than write your own code, you can use an IntBuffer to wrap the existing int[] without having to copy the data into an Integer array:

int[] a = {1, 2, 3, 4};
IntBuffer b = IntBuffer.wrap(a);

IntBuffer implements comparable, so you are able to use the code you already have written. Formally, maps compare keys such that a.equals(b) is used to say two keys are equal, so two IntBuffers with array 1,2,3 - even if the arrays are in different memory locations - are said to be equal and so will work for your frequency code.

ArrayList<int[]> data = ... // Load a dataset`

Map<IntBuffer, Double> frequencies = new HashMap<IntBuffer, Double>();

for(int[] a : data) {

    IntBuffer q = IntBuffer.wrap(a);

    if(frequencies.containsKey(q)) {
        frequencies.put(q, tfs.get(q) + p);
    } else {
        frequencies.put(q, p);
    }
}

You don't need it. int[] is an object and can be used as a key inside a map.

Map<int[], Double> frequencies = new HashMap<int[], Double>();

is the proper definition of the frequencies map.

This was wrong :-). The proper solution is posted too :-).

Related