3

I have an int array with elements 0. I want to remove those elements and reduce the size of my array.

I read an example for String array in Removing empty element from Array(Java) and apply it to my case:

int[] in1 = {0, 0, 2, 0, 3};
int[] in1 = Arrays.stream(in1).filter(x -> x != 0).toArray(int[]::new);

Unfortunately, I receive an error:

The method toArray() in the type IntStream is not applicable for the arguments (int[]::new)

My questions are:

  1. How can I achieve my goal?
  2. Why can't I filter my int array the same way as a String array?
GBlodgett
  • 12,704
  • 4
  • 31
  • 45
Riji
  • 340
  • 2
  • 10

3 Answers3

4

For a primitive int[] don't supply arguments to toArray():

in1 = Arrays.stream(in1).filter(x -> x != 0).toArray();

Also notice that you do not prefix in1 with int[] again, since you have already defined the variable in1

The reason why it doesn't work the same way as the other question is because Arrays.stream(int[]) returns an IntStream which has a version of toArray() which returns an int[].

Using

Arrays.stream(new String[]{"This","", "will", "", "", "work"})

will call Arrays.stream(T[] array), which:

Returns a sequential Stream with the specified array as its source.

Or a Stream<String>. Then using toArray() from the Stream class will be calling this version, which accepts an IntFunction, which will convert it to a specific type of Array. (The toArray() method that accepts no arguments from Stream returns an Object[])

GBlodgett
  • 12,704
  • 4
  • 31
  • 45
1

As we know, primitive types are not object in java, for them there are overloaded stream()method in Arrays class. Suppose here just consider int. If we pass int[] then stream(int[] array) getting called and returns IntStream object. If you go and see IntStream class then you will find only one toArraymethod, which doesn't accepting any arguments.

So, we can't do toArray(int[]::new).

int[] in1 = {0, 0, 2, 0, 3}; int[] in2 = Arrays.stream(in1).filter(x -> x != 0).toArray();

But for any Reference type array, we can convert to specific type. e.g

String[] str2 = {"a","b",null,"c"};
    String[] strArr = Arrays.stream(str2).filter(i -> !=null).toArray(String[]::new);
    for (String string : strArr) {
        System.out.println(string);
    }

In the Reference type case, a generic stream method gets called from Arrays class and produces Stream<T>, now Stream interface has two overloaded toArray(). If we use

  1. toArray() then yield Object[], in this case we need to caste.
  2. toArray(IntFunction<A[]> generator) then give us A[], where A is any reference type.

See below example

package test;
import java.util.Arrays;
public class EliminateZeroFromIntArray {
public static void main(String[] args) {

    int[] in1 = {0, 0, 2, 0, 3};
    int[] in2 = Arrays.stream(in1).filter(x -> x != 0).toArray();
    for (int i : in2) {
        System.out.println(i);
    }

    String[] str = {"a","b",null,"c"};
    Object[] array = Arrays.stream(str).filter(i -> i !=null).toArray();

    for (Object object : array) {
        System.out.println((String)object);
    }

    String[] str2 = {"a","b",null,"c"};
    String[] strArr = Arrays.stream(str2).filter(i -> i !=null).toArray(String[]::new);
    for (String string : strArr) {
        System.out.println(string);
    }
}

}

Dilip Chauhan
  • 147
  • 2
  • 10
0

This probably isn't the best version of this you'll find but:

private int[] removeZeros(int[] array, int toRemove)
    {
        int count = 0;
        int arrayLength = array.length;

        for (int i = 0; i < array.length; i++)
        {
            if (array[i] == toRemove)
                count++;
        }

        int[] newArray = new int[arrayLength - count];
        int j = 0;
        for (int i = 0; i < array.length; i++)
        {
            if (array[i] != toRemove)
            {
                newArray[j] = array[i];
                j++;
            }
        }
        return newArray;
    }
Julian Peffer
  • 307
  • 1
  • 4