如何从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
。
有几件事:
-
Don't you want
String [] a2 = new String [a.length-1];`是的
String[] a2 = new String[a.length];
不会让它变length - 1
会让它太短吗?
-
您需要在代码中使用
i == j
的大小写。 这就是为什么空值没有得到更新。 -
你试图用第二个函数解决什么问题? 鉴于我认为你的问题是什么,这似乎很复杂。
试试这个(我没试过):
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元素:)
问候!
你有两个选择:
-
创建长度与输入相同的新数组,然后为其分配非空值,并将其减去非空元素的计数。
0xJoKe答案中的示例。
-
如果你只需要工作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);
(我发布这个可能会对适用性,相对性能等有所了解)