2011-08-29 151 views
2

我已經寫了一個方法來從程序中需要的數組中刪除空值。然而,該方法似乎並不奏效,空值不會消失。這是我的代碼到目前爲止。如何從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(j<i) 
      { 
       a2[j]=a[j]; 
      } 
     else if(j>i) 
     { 
      a2[j]=a[j+1]; 
     } 
    } 

    a=a2; 
} 

在此先感謝!

+0

這裏可能同樣的問題[!鏈接](http://stackoverflow.com/questions/4150233/remove-null-value-from-string-array-in -java) – Gatekeeper

+0

是否有可能不允許空值進入數組? –

回答

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

我可以看到你的代碼的兩個錯誤:

  • 你的方法fillArray沒有覆蓋的情況下i == j
  • 你分配a = a2;沒有你認爲它可能有效果。參數在Java中以值傳遞,並且您的分配不會在第一個方法中更改值a。嘗試將實例返回a2,fillArray,並將此值分配給removeNull中的a
0

幾件事情:

  1. Don't you want字符串[] A2 =新的String [則爲a.length-1];`是

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

會不會使它length - 1使它太短?

  1. 您的代碼需要一個i == j的情況。這就是空值沒有更新的原因。

  2. 你想用第二個函數解決什麼問題?看起來很複雜,因爲我認爲你的問題是。

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

你爲什麼要在最後複製它ret? –

+0

因爲可能不是每個字段都是必需的(這意味着我在末尾有空值) – 0xJoKe

5

我會主張這樣做的簡單的方法,除非性能真的有問題:

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]); 
} 
+2

+1 - 最簡單的代碼是最好的,除非存在對性能的*真實*需求。 –

+0

+1你真的想給'remove'變量賦一個'ArrayList'類型嗎?我在想'列表',以儘量減少對實際類型的依賴。 – KLE

+0

@KLE如果我返回ArrayList,這將是一個好主意,因爲我可能想通過多態性來更改實現,但對於小方法內的類型,這並不重要。 –

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); 
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優化該代碼。我希望代碼有效。

+0

我不認爲你可以使用arrayCopy進行優化。使用arrayCopy的任何好處都會在你計算出使用它的時間內消失。我能想到的唯一優化是測試nullCount是否爲零,如果是,返回原始數組。 –

0

你有兩個選擇:

  1. 創建新數組的長度是一樣的輸入,然後分配給它不是空值與它。減去添加到NOT NULL elememts的計數。

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

然後在源代碼中,只有你要做的事情是:

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

第二個選擇是很花哨的用法= NULL條件BU它可能是helful時的方法需要返回一些數據。

0

好,越來越多的人之前說的...但我也想強調這一點的解決方案:

您可以使用某種類型的集合,如ArrayList或列表,並添加只有未null元素。最後,你必須返回由集合形成的新的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"); 
    } 
} 

的與代碼不顯示任何信息的原因有任何null元素:)

商祺!

0

這樣會更快:

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