我编写了一个方法来从程序中需要的数组中删除空值。 但是,该方法似乎不起作用,空值不会消失。到目前为止,这是我的代码。
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(j<i)
{
a2[j]=a[j];
}
else if(j>i)
{
a2[j]=a[j+1];
}
}
a=a2;
}
提前致谢!
答案 0 :(得分:6)
除非性能确实是一个问题,否则我会主张以简单的方式去做:
public String[] removeNull(String[] a) {
ArrayList<String> removedNull = new ArrayList<String>();
for (String str : a)
if (str != null)
removedNull.add(str);
return removedNull.toArray(new String[0]);
}
答案 1 :(得分:4)
嗨大家首先,我想为我的英语即时学习道歉,这是我的第一篇文章,所以我想尝试在这里解决问题的解决方案
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;
}
答案 2 :(得分:3)
该解决方案的Streams API版本:
SELECT a, b FROM TABLE WHERE id IN(?,?,?)
(我将其发布下来可能是对适用性,相对性能等有一些想法)
答案 3 :(得分:2)
您无法更改方法中对变量的引用,并希望它反映在调用方法中。
您必须返回新阵列。
public String[] removeNull(String[] a)
{
for(int i=0; i<a.length; i++)
{
if(a[i] == null)
{
a = fillArray(a, i);
}
}
return a;
}
public String[] fillArray(String[] a, int i)
{
String[] a2 = new String[a.length-1];
for(int j=0; j<a2.length; j++)
{
if(j<i)
{
a2[j]=a[j];
}
else if(j>i)
{
a2[j]=a[j+1];
}
}
return a2;
}
答案 4 :(得分:1)
我可以在您的代码中看到两个错误:
fillArray
不包括案例i == j
a = a2;
没有您认为可能产生的效果。参数在Java中按值传递,并且您的赋值不会在第一个方法中更改a
的值。尝试将实例返回到a2
中的fillArray
,并将此值分配给a
中的removeNull
。答案 5 :(得分:1)
这种方式会更快:
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);
}
答案 6 :(得分:0)
有几件事:
Don't you want
String [] a2 = new String [a.length-1];`to be String[] a2 = new String[a.length];
不会让它length - 1
太短了吗?
您的代码中需要i == j
的案例。这就是为什么空值没有得到更新。
您尝试使用第二个功能解决了什么问题?考虑到我认为你的问题,这似乎很复杂。
答案 7 :(得分:0)
试试这个(我没试过):
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;
}
答案 8 :(得分:0)
删除数组中的值时,大小会发生变化,因此您无法保持相同的数组(可以在末尾推送空值)。
靠近具有可自动调整大小的数组的结构是ArrayList。一种选择是:
String[] inputs;
List<String> items = new ArrayList<String>(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);
答案 9 :(得分:0)
这样你就可以在一个循环中删除空值,但不会调整数组的大小:
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
优化该代码。我希望代码有效。
答案 10 :(得分:0)
您有两种选择:
创建长度与输入相同的新数组,然后为其分配非空值,并将其减去非空元素的数量。
0xJoKe回答中的示例。
如果您只需要处理sutch数组,则可以为其创建适配器。
public class NullProofIterable<T> implements Iterable<T>{
private final T[] array;
public NullProofIterable(T[] array){
this.array = array;
}
@Override
public Iterator<T> iterator() {
return new NullProofIterator<T>(this.array);
}
private static class NullProofIterator<T> implements Iterator<T> {
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<String>(strArray)) {
//Perform action on not null string
}
第二个选项是非常奇特的使用!= null条件,当方法需要返回一些数据时,它可能会很有用。
答案 11 :(得分:0)
嗯,之前有更多人说过......但我也想强调这个解决方案:
您可以使用某种类型的Collection,例如ArrayList或List,并仅添加非null元素。最后,您必须返回由Collection形成的新String []。
这是一个可以检查正确性的示例:
import java.util.ArrayList;
public class NullRemove {
public static String[] removeNull(String[] a) {
ArrayList<String> aux = new ArrayList<String>();
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元素:)
问候!