如何高效地从ArrayList或String数组中删除所有空元素?

215
我尝试使用如下循环:
// ArrayList tourists

for (Tourist t : tourists) {
    if (t != null) {     
        t.setId(idForm); 
    }   
}

但这不是一个好的解决方案。有没有人可以提供更好的建议?


一些有用的基准测试,以做出更好的决策:

While 循环,For 循环和迭代器性能测试


2
要使用Iterator吗?查看java-doc。http://download.oracle.com/javase/6/docs/api/java/util/Iterator.html#remove(​) - Nishant
由于您的基准参考,似乎您将“好”/“更好”定义为基准化的“效率”。而您的参考本身似乎得出了答案:“迭代器循环最慢,for循环和while循环之间的差异并不那么显著。” - cellepo
18个回答

3

有一种简单的方法可以从collection中删除所有的null值。您只需要将包含null的集合作为参数传递给removeAll()方法即可。

List s1=new ArrayList();
s1.add(null);

yourCollection.removeAll(s1);

这对我来说是最好的解决方案。它还允许您轻松地添加多个条目到“过滤器数组”中,该数组将传递到原始集合的removeAll方法中。 - user4903

2
这是从ArrayList中轻松删除默认null值的方法。
     tourists.removeAll(Arrays.asList(null));  

否则将字符串值为“null”的元素从ArrayList中移除。
       tourists.removeAll(Arrays.asList("null"));  

1

我使用了流接口,结合流操作collect和一个辅助方法来生成一个新列表。

tourists.stream().filter(this::isNotNull).collect(Collectors.toList());

private <T> boolean isNotNull(final T item) {
    return  item != null;
}

3
tourists.stream().filter(s -> s != null).collect(Collectors.toList()); - 1ac0
tourists.stream().filter(Objects::nonNull).collect(Collectors.toList()) - cellepo

1
我们可以使用迭代器来删除所有的空值。
Iterator<Tourist> itr= tourists.iterator();
while(itr.hasNext()){
    if(itr.next() == null){
        itr.remove();
    }
}

1

我尝试了一下,发现trimToSize()似乎有效。我正在Android平台上工作,所以可能会有所不同。


2
根据Javadoc,trimToSize不会修改ArrayList的内容。如果在Android中有所不同,那很可能是一个bug。 - fabian

0
与@Lithium的答案类似,但不会引发“列表可能不包含类型null”的错误。
   list.removeAll(Collections.<T>singleton(null));

0

使用Java 8,可以通过流、并行流和removeIf方法以多种方式执行此操作:

List<String> stringList = new ArrayList<>(Arrays.asList(null, "A", "B", null, "C", null));
List<String> listWithoutNulls1 = stringList.stream()
                .filter(Objects::nonNull)
                .collect(Collectors.toList()); //[A,B,C]
List<String> listWithoutNulls2 = stringList.parallelStream()
                .filter(Objects::nonNull)
                .collect(Collectors.toList()); //[A,B,C]
stringList.removeIf(Objects::isNull); //[A,B,C]

并行流将利用可用的处理器,并加速适当大小列表的处理过程。在使用流之前,始终建议进行基准测试。


0
List<String> colors = new ArrayList<>(
Arrays.asList("RED", null, "BLUE", null, "GREEN"));
// using removeIf() + Objects.isNull()
colors.removeIf(Objects::isNull);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接