1

Below are the 2 ways to remove null values, which one is the best approach?

public static String[] clean(final String[] v) {
    List<String> list = new ArrayList<String>(Arrays.asList(v));
    list.removeAll(Collections.singleton(null));
    return list.toArray(new String[list.size()]);
}

public static String[] clean(final String[] v) {
    List<String> list = new ArrayList<String>(v.length);
     for (String aString : v)
        {
            if (aString != null)
            {
                list.add(aString);
            }
        }
    return list.toArray(new String[list.size()]);
}
Bernhard Barker
  • 54,589
  • 14
  • 104
  • 138
Satheesh
  • 163
  • 1
  • 3
  • 11
  • 1
    Both will have the same end result. "Better" in what terms? Processing time? Memory usage? Readability? – David ten Hove Jul 23 '15 at 11:00
  • I'd let the List class handle it. i.e. use the first. Both look like a huge waste of performance though. – insidesin Jul 23 '15 at 11:01
  • Studying your suggestions, the real question is [How to remove `null` elements from a list](http://stackoverflow.com/q/8559257/1734119). The question I linked to suggests your first approach. – Chop Jul 23 '15 at 11:02
  • You can also do some Java 8 tricks. Again, it depends on what you consider makes 1 approach better than another. – David ten Hove Jul 23 '15 at 11:02
  • In the second example, why do you initialize your `list` with the same size as `v`? This wont remove your `null` values, or do I miss something? – Alex S. Diaz Jul 23 '15 at 11:16
  • Yes we don't need to initialize the list..!!! I am looking in terms of performance...!! – Satheesh Jul 23 '15 at 12:10

5 Answers5

1

For removing null values from a single string, I would use a regular expression like this,

private static Pattern pattern = Pattern.compile("(?i)[(\\[{]?null[)\\]}]?");

    public static String removeNullString(String value) {
        if (StringUtils.isEmpty(value)) {
            return StringUtils.EMPTY;
        }

        Matcher matcher = pattern.matcher(value);
        return matcher.replaceAll(StringUtils.EMPTY);
    }

It covers up all "null" and empty character from string.

For removing null value from a string array in Java 7,

String[] firstArray = {"test1", "", "test2", "test4", "", null};

    List<String> list = new ArrayList<String>();

    for(String s : firstArray) {
       if(s != null && s.length() > 0) {
          list.add(s);
       }
    }

    firstArray = list.toArray(new String[list.size()]);

For removing null value from a string array in Java 8,

String[] firstArray = {"test1", "", "test2", "test4", "", null};

firstArray = Arrays.stream(firstArray)
                     .filter(s -> (s != null && s.length() > 0))
                     .toArray(String[]::new); 
Prokash Sarkar
  • 11,723
  • 1
  • 37
  • 50
1

Performance wise, it is usually better to minimize calls outside of the scope of the current code block (ie method). Also, since memory allocation is relatively slow compared most other instructions, avoiding object creation is typically a goal. The best I can come up with in terms of performance (I chose to make it flexible enough to take any type of array):

public <T> T[] removeNulls(Class<T> type, final T[] original){

    // first, shift all non-null instances to the head, all nulls to the end.
    int nonNullCount=0;
    T tempT = null;

    for(int i=0; i < original.length; i++){
        if(original[i] != null){
            nonNullCount++;
        }else if(i != original.length - 1){
            // Swap the next non-null value with this null value
            int j = i + 1;
            // In case there are multiple null values in a row
            // scan ahead until we find the next non-null value
            while(j < original.length && (tempT = original[j]) == null){
                j++;
            }
            original[nonNullCount] = tempT;
            if(tempT != null){
                nonNullCount++;
            }
            if(j < original.length){
                original[j] = null;
            }

            i = j - 1;
        }
    }

    // The case where there are no nulls in the array
    if(nonNullCount == original.length){
        return original;
    }

    final T[] noNulls = (T[]) Array.newInstance(type,nonNullCount);
    System.arraycopy(original,0,noNulls,0,nonNullCount);
    return  noNulls;
}

But I'm not sure why you would want this complexity over the 3 or 4 lines to do the same thing when performance is not likely to be an issue. You would need to have HUGE arrays to see any benefit (if any) between my code and your clean example.

MadConan
  • 3,749
  • 1
  • 16
  • 27
0

in Java 8 you should be able to do something like:

List<String> list = new ArrayList<String>(Arrays.asList(v));
list.removeIf(Objects::isNull);
return list.toArray(new String[list.size()]);
Viktor Mellgren
  • 4,318
  • 3
  • 42
  • 75
0

if you want to do it in same space i will suggest the follwing solution. But final array will also be having same size. I mean it will not shrink in size but all elements will get aggregated in same order.

   public static void removeNullFromArray(String[] args) {
      int location = 0;
      for(int i=0;  i<args.length; i++){
         String arg = args[i];
         if(arg!=null){
            if(location<i){
               args[location] = arg;
               args[i] = null;
            }
            location++;
         }
      }
   }
Himanshu Goel
  • 574
  • 1
  • 8
  • 26
0

Java 8 code using streams and lambda. Filters non-nulls from an array and converts to a list.

Arrays.stream(arr).filter(Objects::nonNull).collect(Collectors.toList());
Joe
  • 326
  • 3
  • 11