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

JavaArraysGenericsCollections

Java Problem Overview


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.

Java Solutions


Solution 1 - Java

Native Java 8 (one line)

With Java 8, int[] can be converted to Integer[] easily:

int[] data = {1,2,3,4,5,6,7,8,9,10};

// To boxed array
Integer[] what = Arrays.stream( data ).boxed().toArray( Integer[]::new );
Integer[] ever = IntStream.of( data ).boxed().toArray( Integer[]::new );

// To boxed list
List<Integer> you  = Arrays.stream( data ).boxed().collect( Collectors.toList() );
List<Integer> like = IntStream.of( data ).boxed().collect( Collectors.toList() );

As others stated, Integer[] is usually not a good map key. But as far as conversion goes, we now have a relatively clean and native code.

Solution 2 - Java

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);

Solution 3 - Java

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]);

Solution 4 - Java

Using regular for-loop without external libraries:

Convert int[] to Integer[]:

int[] primitiveArray = {1, 2, 3, 4, 5};
Integer[] objectArray = new Integer[primitiveArray.length];

for(int ctr = 0; ctr < primitiveArray.length; ctr++) {
	objectArray[ctr] = Integer.valueOf(primitiveArray[ctr]); // returns Integer value
}

Convert Integer[] to int[]:

Integer[] objectArray = {1, 2, 3, 4, 5};
int[] primitiveArray = new int[objectArray.length];

for(int ctr = 0; ctr < objectArray.length; ctr++) {
	primitiveArray[ctr] = objectArray[ctr].intValue(); // returns int value
}

Solution 5 - Java

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).

Solution 6 - Java

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);
}

Solution 7 - Java

  1. Convert int[] to Integer[]

     public static Integer[] toConvertInteger(int[] ids) {
    
         Integer[] newArray = new Integer[ids.length];
         for (int i = 0; i < ids.length; i++) {
             newArray[i] = Integer.valueOf(ids[i]);
         }
         return newArray;
     }
    
  2. Convert Integer[] to int[]

     public static int[] toint(Integer[] WrapperArray) {
    
        int[] newArray = new int[WrapperArray.length];
        for (int i = 0; i < WrapperArray.length; i++) {
            newArray[i] = WrapperArray[i].intValue();
        }
        return newArray;
     }
    

Solution 8 - Java

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);
    }
}

Solution 9 - Java

I am not sure why you need a Double in your map. In terms of what you're trying to do, you have an int[] and you just want counts of how many times each sequence occurs(?). Why would this require a Double anyway?

I would create a wrapper for the int array with a proper .equals and .hashCode methods to account for the fact that int[] object itself doesn't consider the data in its version of these methods.

public class IntArrayWrapper {
    private int values[];

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

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + Arrays.hashCode(values);
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        IntArrayWrapper other = (IntArrayWrapper) obj;
        if (!Arrays.equals(values, other.values))
            return false;
        return true;
    }

}

And then use Google Guava's multiset, which is meant exactly for the purpose of counting occurrences, as long as the element type you put in it has proper .equals and .hashCode methods.

List<int[]> list = ...;
HashMultiset<IntArrayWrapper> multiset = HashMultiset.create();
for (int values[] : list) {
    multiset.add(new IntArrayWrapper(values));
}

Then, to get the count for any particular combination:

int cnt = multiset.count(new IntArrayWrapper(new int[] { 0, 1, 2, 3 }));

Solution 10 - Java

This worked like a charm!

int[] mInt = new int[10];
Integer[] mInteger = new Integer[mInt.length];

List<Integer> wrapper = new AbstractList<Integer>() {
    @Override
    public int size() {
        return mInt.length;
    }

    @Override
    public Integer get(int i) {
        return mInt[i];
    }
};

wrapper.toArray(mInteger);

Solution 11 - Java

Though the below compiles, it throws a ArrayStoreException at runtime.


Converting an int[], to an Integer[]:

int[] old;
...
Integer[] arr = new Integer[old.length];
System.arraycopy(old, 0, arr, 0, old.length);

I must admit I was a bit surprised that this compiles, given System.arraycopy being lowlevel and everything, but it does. At least in Java 7.

You can convert the other way just as easily.

Solution 12 - Java

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 :-).

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJohnView Question on Stackoverflow
Solution 1 - JavaSheepyView Answer on Stackoverflow
Solution 2 - JavaEddieView Answer on Stackoverflow
Solution 3 - JavazemiakView Answer on Stackoverflow
Solution 4 - JavasilverView Answer on Stackoverflow
Solution 5 - JavaTom Hawtin - tacklineView Answer on Stackoverflow
Solution 6 - JavaMihai ToaderView Answer on Stackoverflow
Solution 7 - JavaHarshView Answer on Stackoverflow
Solution 8 - JavaChrisView Answer on Stackoverflow
Solution 9 - JavaMattView Answer on Stackoverflow
Solution 10 - JavaItamar BorgesView Answer on Stackoverflow
Solution 11 - JavaThomas AhleView Answer on Stackoverflow
Solution 12 - JavaMihai ToaderView Answer on Stackoverflow