簡體   English   中英

在 Java 中,從字符串列表中刪除空元素

[英]In Java, remove empty elements from a list of Strings

在 Java 中,我有一個字符串的 ArrayList,例如:

[,Hi, ,How,are,you]

我想刪除空元素和空元素,如何更改它是這樣的:

[Hi,How,are,you]
List<String> list = new ArrayList<String>(Arrays.asList("", "Hi", null, "How"));
System.out.println(list);
list.removeAll(Arrays.asList("", null));
System.out.println(list);

輸出:

[, Hi, null, How]
[Hi, How]

這是一個很晚的答案,但您也可以使用Collections.singleton

List<String> list = new ArrayList<String>(Arrays.asList("", "Hi", null, "How"));
list.removeAll(Collections.singleton(null));
list.removeAll(Collections.singleton(""));

既然我們有了 Java 8 lambda 表達式,那么另一種方式來做到這一點。

arrayList.removeIf(item -> item == null || "".equals(item));

如果您使用的是Java 8那就試試這個使用lambda表達式和org.apache.commons.lang.StringUtils ,這也將清除nullblank值從array輸入

public static String[] cleanArray(String[] array) {
    return Arrays.stream(array).filter(x -> !StringUtils.isBlank(x)).toArray(String[]::new);
}

參考 - https://stackoverflow.com/a/41935895/9696526

  1. 如果您詢問如何刪除空字符串,您可以這樣做(其中l是一個ArrayList<String> ) - 這將刪除所有null引用和長度為 0 的字符串:

     Iterator<String> i = l.iterator(); while (i.hasNext()) { String s = i.next(); if (s == null || s.isEmpty()) { i.remove(); } }
  2. 不要將ArrayList與數組混淆, ArrayList是一種動態數據結構,可根據其內容調整大小。 如果你使用上面的代碼,你不需要做任何事情來得到你描述的結果 - 如果你的ArrayList是 ["","Hi","","How","are"," you"],按照上述方法刪除后,它將正是您所需要的 - ["Hi","How","are","you"]

    但是,如果您必須擁有原始列表的“清理”副本(同時保留原始列表)並且“將其存儲回”您的意思是“制作副本”,那么另一個答案中的 krmby 代碼將為您服務美好的。

要把這個小金塊放在這兒:

Stream.of("", "Hi", null, "How", "are", "you")
  .filter(t -> !Strings.isNullOrEmpty(t))
  .collect(ImmutableList.toImmutableList());

我衷心希望 Java 有一個filterNot

您可以使用以下幾種方法:

  1. 遍歷列表,為要刪除的列表元素調用Iterator.remove() 這是最簡單的。

  2. 重復調用List.remove(Object) 這也很簡單,但最糟糕的是……因為您反復掃描整個列表 (但是,這可能是可變列表的一個選項,它的迭代器由於某種原因不支持remove ...。)

  3. 創建一個新列表,迭代舊列表,將要保留的元素添加到新列表中。

  4. 如果你不能返回新列表,如上面的3.然后清除舊列表並使用addAll將新列表的元素添加回它。

其中哪一個最快取決於原始列表的類、它的大小以及需要刪除的元素數量。 以下是一些因素:

  • 對於ArrayList ,每個單獨的remove操作都是O(N) ,其中N是列表大小。 使用Iterator.remove()方法(或ArrayList.remove(element)方法)從大型 ArrayList 中刪除多個元素的成本很高。

    相比之下, LinkedListIterator.remove方法是O(1)

  • 對於ArrayList ,創建和復制列表是O(N)並且相對便宜,特別是如果您可以確保目標列表的容量足夠大(但不要太大)。

    相比之下,創建和復制到LinkedList也是O(N) ,但要貴得多。

所有這些加起來構成了一個相當復雜的決策樹。 如果列表很小(比如 10 個或更少的元素),您可能可以使用上述任何方法。 如果列表可能很大,您需要權衡預期列表大小和預期刪除數量列表中的所有問題。 (否則你可能會得到二次性能。)

  • 此代碼編譯並順利運行。
  • 它不使用迭代器,因此更具可讀性。
  • list 是你的收藏。
  • 結果是過濾形式(非空非空)。

public static void listRemove() {
    List<String> list = Arrays.asList("", "Hi", "", "How", "are", "you");
    List<String> result = new ArrayList<String>();

    for (String str : list) {
        if (str != null && !str.isEmpty()) {
            result.add(str);
        }
    }

    System.out.println(result);
}

如果您使用上述答案之一獲得UnsupportedOperationException並且您的List是從Arrays.asList()創建的,那是因為您無法編輯此類List

要修復,請將Arrays.asList()包裝在new LinkedList<String>()

    List<String> list = new LinkedList<String>(Arrays.asList(split));

來源來自這個答案

關於 Andrew Mairose 的評論 - 雖然是一個很好的解決方案,但我只想補充一點,該解決方案不適用於固定大小的列表。

你可以嘗試這樣做:

Arrays.asList(new String[]{"a", "b", null, "c", "    "})
    .removeIf(item -> item == null || "".equals(item));

但是您會UnsupportedOperationException at java.util.AbstractList.remove遇到UnsupportedOperationException at java.util.AbstractList.remove (因為asList返回一個不可調整大小的列表)。

一個不同的解決方案可能是這樣的:

List<String> collect =
    Stream.of(new String[]{"a", "b", "c", null, ""})
        .filter(item -> item != null && !"".equals(item))
        .collect(Collectors.toList());

這將產生一個很好的字符串列表:-)

   private List cleanInputs(String[] inputArray) {
        List<String> result = new ArrayList<String>(inputArray.length);
        for (String input : inputArray) {
            if (input != null) {
                String str = input.trim();
                if (!str.isEmpty()) {
                    result.add(str);
                }
            }
        }
        return result;
    }
List<String> list = new ArrayList<String>(Arrays.asList("", "Hi", "", "How"));
           Stream<String> stream = list .stream();
           Predicate<String> empty = empt->(empt.equals(""));
            Predicate<String> emptyRev = empty.negate();
           list=  stream.filter(emptyRev).collect(Collectors.toList());

或者

list =  list .stream().filter(empty->(!empty.equals(""))).collect(Collectors.toList());

lukastymo 的答案似乎是最好的答案。

但值得一提的是這種方法以及它的可擴展性:

List<String> list = new ArrayList<String>(Arrays.asList("", "Hi", null, "How", "are"));

list = list.stream()
           .filter(item -> item != null && !item.isEmpty())
           .collect(Collectors.toList());

System.out.println(list);

我的意思是你可以添加額外的過濾器,例如:

          .filter(item -> !item.startsWith("a"))

...當然,這與問題沒有特別的關系。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM