如何从java中的数组中删除null

我编写了一个方法来从程序中需要的数组中删除空值。 但是,该方法似乎不起作用,空值不会消失。 到目前为止这是我的代码。

public void removeNull(String[] a) { for(int i=0; i<a.length; i++) { if(a[i] == null) { fillArray(a, i); } } } public void fillArray(String[] a, int i) { String[] a2 = new String[a.length-1]; for(int j=0; j<a2.length; j++) { if(ji) { a2[j]=a[j+1]; } } a=a2; } 

提前致谢!

除非性能确实是一个问题,否则我会主张以简单的方式做到这一点:

 public String[] removeNull(String[] a) { ArrayList removedNull = new ArrayList(); for (String str : a) if (str != null) removedNull.add(str); return removedNull.toArray(new String[0]); } 

您无法更改方法中对变量的引用,并期望它反映在调用方法中。

你将不得不返回新的数组。

 public String[] removeNull(String[] a) { for(int i=0; ii) { a2[j]=a[j+1]; } } return a2; } 

大家好,首先我想为我的英语即时通讯学习,这是我的第一篇文章所以我想尝试在这里解决问题的解决方案

 String[] removeNulls(String[] nullsArray) { int countNulls = 0; for (int i = 0; i < nullsArray.length; i++) { // count nulls in array if (nullsArray[i] == null) { countNulls++; } } // creating new array with new length (length of first array - counted nulls) String[] nullsRemoved = new String[nullsArray.length - countNulls]; for (int i = 0, j = 0; i < nullsArray.length; i++) { if (nullsArray[i] != null) { nullsRemoved[j] = nullsArray[i]; j++; } } return nullsRemoved; } 

我可以在你的代码中看到两个错误:

  • 你的方法fillArray不包括i == j的情况
  • 你的任命a = a2; 没有你认为它可能具有的效果。 参数在Java中按值传递,并且您的赋值不会在第一个方法中更改a的值。 尝试在fillArray实例返回到a2 ,并将此值分配给removeNull中的removeNull

有几件事:

  1. Don't you want String [] a2 = new String [a.length-1];`是的

String[] a2 = new String[a.length];

不会让它变length - 1会让它太短吗?

  1. 您需要在代码中使用i == j的大小写。 这就是为什么空值没有得到更新。

  2. 你试图用第二个函数解决什么问题? 鉴于我认为你的问题是什么,这似乎很复杂。

试试这个(我没试过):

 public String[] removeNull(String[] a) { String[] tmp = new String[a.length]; int counter = 0; for (String s : a) { if (s != null) { tmp[counter++] = s; } } String[] ret = new String[counter]; System.arraycopy(tmp, 0, ret, 0, counter); return ret; } 

这样您可以在一个周期中删除空值,但不会调整数组的大小:

 public static void removeNull(String[] a) { int nullCount = 0; for (int i = 0; i < a.length; i++) { if (a[i] == null) { nullCount++; } else { a[i-nullCount] = a[i]; } } } 

这个创建新数组,但包括两个周期:

 public static String[] removeNull(String[] a) { int nullCount = 0; for (int i = 0; i < a.length; i++) { if (a[i] == null) nullCount++; } String[] b = new String[a.length-nullCount]; int j = 0; for (int i = 0; i < a.length; i++) { if (a[i] != null) b[j++] = a[i]; } return b; } 

您可以考虑使用System.arraycopy优化该代码。 我希望代码有效。

删除数组中的值时,大小会更改,因此您无法保持相同的数组(您可以在末尾推送空值)。

靠近具有可自动resize的数组的结构是ArrayList。 一种选择是:

 String[] inputs; List items = new ArrayList(inputs.length); for(String input : inputs) { if (input != null) { items.add(input); } } String[] outputs = items.toArray(new String[items.size()]); 

性能可能比直接使用数组少一些,但由于数组具有固定大小,因此需要两个带数组的循环:

  • 一个来计算非空值的数量
  • 在构建数组之后,使用相同的循环来复制值。

这可能也没有理想的性能,而且要做到这一点真的要复杂得多……


另一种方法是在末尾移动空值,然后创建一个不包含空值的较短数组。 这个想法是:

 String[] strings; int writeIndex = 0; int max = strings.length; for(int readIndex = 0; readIndex < max; readIndex++) { String read = strings[readIndex]; if (read != null) { strings[writeIndex++] = read; } } String[] outputs = new String[writeIndex]; System.arraycopy(strings, 0, ouputs, 0, writeIndex); 

好吧,之前有更多人说过……但我也想强调这个解决方案:

您可以使用某种类型的Collection,如ArrayList或List,并仅添加非null元素。 最后,您必须返回Collection形成的新String []。

这是一个可以检查正确性的示例:

 import java.util.ArrayList; public class NullRemove { public static String[] removeNull(String[] a) { ArrayList aux = new ArrayList(); for (String elem : a) { if (elem != null) { aux.add(elem); } } return (String[]) aux.toArray(new String[aux.size()]); } public static void main(String[] args) { String[] init = new String[]{"aaa", null, "bbb", "ccc", null, "ddd", "eee", "fff", null}; String[] result = NullRemove.removeNull(init); System.out.println("Start Check result"); for (String elem : result) { if (elem == null) System.out.println("NULL element"); } System.out.println("End Check result"); } } 

带代码的for不打印任何因为有任何null元素:)

问候!

你有两个选择:

  1. 创建长度与输入相同的新数组,然后为其分配非空值,并将其减去非空元素的计数。

    0xJoKe答案中的示例。

  2. 如果你只需要工作sutch数组,你可以为它创建一个适配器。

     public class NullProofIterable implements Iterable{ private final T[] array; public NullProofIterable(T[] array){ this.array = array; } @Override public Iterator iterator() { return new NullProofIterator(this.array); } private static class NullProofIterator implements Iterator { private final T[] array; private final int index = 0; private NullProofIterator(T[] array) { this.array = array; } @Override public boolean hasNext() { return this.index < this.array.length; } @Override public T next() { return this.array[this.index]; } @Override public void remove() { throw new RuntimeException("Remove not allowed in this iterator"); } } } 

然后在源代码中,您唯一需要做的就是:

 for(String str : new NullProofIterable(strArray)) { //Perform action on not null string } 

第二个选项是非常奇特的使用!= null条件,当方法需要返回一些数据时,它可能很有用。

这种方式会更快:

 private static String[] removeNulls(String[] strs) { int i = 0; int j = strs.length - 1; while (i <= j) { if (strs[j] == null) { --j; } else if (strs[i] != null) { ++i; } else { strs[i] = strs[j]; strs[j] = null; ++i; --j; } } return Arrays.copyOfRange(strs, 0, i); } 

Streams API版本的解决方案:

 SomeClass[] array = new SomeClass[N]; ... array = Arrays.stream(array).filter(Objects::nonNull).toArray(SomeClass[]::new); 

(我发布这个可能会对适用性,相对性能等有所了解)