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

时间:2011-08-29 12:51:44

标签: java arrays

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

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;
}

提前致谢!

12 个答案:

答案 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)

有几件事:

  1. Don't you want String [] a2 = new String [a.length-1];`to be
  2. String[] a2 = new String[a.length];

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

    1. 您的代码中需要i == j的案例。这就是为什么空值没有得到更新。

    2. 您尝试使用第二个功能解决了什么问题?考虑到我认为你的问题,这似乎很复杂。

答案 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)

您有两种选择:

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

    0xJoKe回答中的示例。

  2. 如果您只需要处理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");
        }
    
    }
    
    }
    
  3. 然后在源代码中,您唯一需要做的就是:

    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元素:)

问候!