11

I have following String Array tmp = [null, null, null, Mars, Saturn, Mars] coming after doing the operation - allSig[d3].split(" "); where allSig is an array of Strings. The null value is empty value in the array. Now I want to remove the null. For this I am using

tmp[indexNumber] != null is not working and giving true ; taking null as the value. Even if i am using "null" as a string is not working.

How to remove this.

public static String[] removeElements(String[] allElements) {
    String[] _localAllElements = new String[allElements.length];

    for (int i = 0; i < allElements.length; i++)
        if (allElements[i] != null)
            _localAllElements[i] = allElements[i];

    return _localAllElements;
}
3
  • Are the "null" always together at the beginning or end? Commented Aug 17, 2012 at 8:25
  • No First i created a array by this way - String[] x= new String[10]; then I added in the value by this way - x[a8] += " " + planetName1Tr[a9]; in this scenario in null value is added that is lyk - "null Sun Moon" etc. Now I want to remove this null. Commented Aug 17, 2012 at 8:32
  • You can probably avoid having to clean anything at all. Commented Aug 17, 2012 at 8:51

6 Answers 6

2
public static String[] clean(final String[] v) {
  int r, w;
  final int n = r = w = v.length;
  while (r > 0) {
    final String s = v[--r];
    if (!s.equals("null")) {
      v[--w] = s;
    }
  }
  return Arrays.copyOfRange(v, w, n);
}

or

public static String[] clean(final String[] v) {
  int r, w, n = r = w = v.length;
  while (r > 0) {
    final String s = v[--r];
    if (!s.equals("null")) {
      v[--w] = s;
    }
  }
  final String[] c = new String[n -= w];
  System.arraycopy(v, w, c, 0, n);
  return c;
}

Works fine...

public static void main(final String[] argv) {
  final String[] source = new String[] { "Mars", "null", "Saturn", "null", "Mars" };
  assert Arrays.equals(clean(source), new String[] { "Mars", "Saturn", "Mars" });
}
Sign up to request clarification or add additional context in comments.

Comments

2

You're creating an array with same size as the original one. So it's the same as the original array, as you copy non null values and default values are null.

Do this :

public static String[] removeElements(String[] allElements) {
    // 1 : count
    int n = 0;
    for (int i = 0; i < allElements.length; i++)
        if (allElements[i] != null) n++;

    // 2 : allocate new array
    String[] _localAllElements = new String[n];

    // 3 : copy not null elements
    int j = 0;
    for (int i = 0; i < allElements.length; i++)
        if (allElements[i] != null)
            _localAllElements[j++] = allElements[i];

    return _localAllElements;
}

6 Comments

No reason at all for doing 2 passes.
@veer you need the number of not null strings to allocate a well sized array. Or you need to do another copy after, which is more expensive.
you only have to check for null once!
actually Arrays.copyOf is probably as fast as the manual copy you're doing, not to mention you'd have to compare each element against "null" twice ;)
You're changing the initial array. I don't. That's the reason you seem to make only one copy operation. But this is a detail.
|
2

Abstracting @az answer, this applies to any class type:

@SuppressWarnings("unchecked")
public static <T> T[] clean(T[] a) {
    List<T> list = new ArrayList<T>(Arrays.asList(a));
    list.removeAll(Collections.singleton(null));
    return list.toArray((T[]) Array.newInstance(a.getClass().getComponentType(), list.size()));
}

Comments

1

If you want the array to contain only the non-null values (i.e. the resulting array would be ["Mars", "Saturn", "Mars"]), then I would look at this as a two part problem.

First, you must identify what the size of the new array should be. From inspection, it's easy to see that it's 3, but you will need to need to count them to calculate this programmatically. You can do this by saying:

// Calculate the size for the new array.
int newSize = 0;
for (int i = 0; i < allElements.length; i++)    {
    if (allElements[i] != null) {
        newSize++;
    }
}

Secondly, you will need to create a new array with that size. Then you can put all of the non-null elements into your new array, as you have done above.

// Populate the new array.
String[] _localAllElements = new String[newSize];
int newIndex = 0;
for (int i = 0; i < allElements.length; i++) {
    if (allElements[i] != null) {
        _localAllElements[newIndex] = allElements[i];
        newIndex++;
    }
}

// Return the new array.
return _localAllElements;

You can just combine these two components as the new content of your results method. See the full combined code and live sample output here.

Comments

0
public static String[] removeElements(String[] allElements) {
    String[] _localAllElements = new String[allElements.length];
    int j = 0;
    for (int i = 0; i < allElements.length; i++)
        if ( allElements[i] != null && !allElements[i].equals(""))
            _localAllElements[j++] = allElements[i];

    return _localAllElements;
}

1 Comment

this is not working, it leaves null strings at the end of the new String Array if null or "" is found
0

This is a very old question but this Java 8+ solution might be useful to someone:

public static String[] removeElements(String[] allElements) { return Arrays.stream(allElements) .filter(Objects::nonNull) .collect(Collectors.toArray()); } or if you, like me, are a fan of readable code and don't want static methods to get in your way, you can simplify this even further using static imports:

public static String[] removeElements(String[] allElements) { return stream(allElements).filter(Objects::nonNull).collect(toArray()); }

1 Comment

There is no Collectors.toArray(). To get a String[] from a Stream, you have to invoke .toArray(String[]::new) directly on the Stream.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.