帮助删除Java列表中的空引用?

鉴于以下列表:

List<String> list = new ArrayList<String>(); list.add("s1"); list.add("s2"); list.add(null); list.add("s3"); list.add(null); list.add("s4"); 

我需要一个帮助类,删除空引用。 就像是:

SomeHelper.removeNullReference(名单);

使列表只包含“s1”,“s2”,“s4”,“s4”(非空引用)。

我应该用什么来满足这个要求?

 list.removeAll(Collections.singleton(null)); 

如果你可以控制List的实例化,那么你可以通过编写一个自定义的List实现来防止被添加的null,例如:

 public class NoNullsList<E> extends ArrayList<E> { public void add(int index, E element) { if (element != null) { super.add(index, element); } } public boolean add(E e) { return e == null ? false : super.add(e); } } 

AFAIK,你不需要重载addAll因为它的ArrayList实现调用add

 List<String> list = new NoNullsList<String>(); list.add("s1"); list.add("s2"); list.add(null); list.add("s3"); list.add(null); list.add("s4"); 

Don的方法的缺点是它从ArrayList扩展。 现在可能已经足够了,但是当你想使用不同的List实现时会发生什么呢? 你可以创build一个NoNullsLinkedList和一个NoNullsCopyOnWriteArrayList等等,但是最后你会得到一堆仅在其extends子句中有所不同的NoNullsCopyOnWriteArrayList 。 创build一个不接受空值的List包装可能会更好。 例如:

 public class NonNullList<E> extends AbstractList<E> { private final List<E> delegate; public NonNullList(List<E> delegate) { this.delegate = delegate; } @Override public E get(int index) { return delegate.get( index ); } @Override public int size() { return delegate.size(); } @Override public E set(int index, E element) { return delegate.set( index, element ); } @Override public void add(int index, E element) { if( element != null ) { delegate.add( index, element ); } } @Override public E remove(int index) { return delegate.remove( index ); } } 

这是更多的代码,但是现在您可以灵活地在创build对象时selectList实现。

一个可能的问题是,你仍然可以将null插入到底层的List对象中。 唐的做法没有相同的限制。

Java 8添加了Collection.removeIf(Predicate) ,它删除了与谓词匹配的所有元素,所以你可以从列表(或任何集合)中删除所有出现的null

 list.removeIf(Objects::isNull); 

使用java.util.Objects.isNull作为Predicate

如果您愿意,也可以使用.removeIf(x -> x == null) 。 差别很小 。

我非常喜欢Java 8的新简洁解决scheme,我相信你应该尽可能地使用它。

 list.removeIf(Objects::isNull); 

另一方面,如果你正在寻找一个简单的实现来学习如何完成,例如返回新的非空列表的帮助类,你可以看看下面的代码。 也可以使用接受genericstypes,为了简单起见,我在助手类中使用了相同的集合types(如在问题中)。

 package removenullrefdemo; import java.util.ArrayList; import java.util.List; import java.util.Objects; class ListHelper { public static List<String> removeNullReference(List<String> list) { List<String> newList = new ArrayList<>(); list.forEach(item -> { if (item != null) newList.add(item); }); return newList; } } public class Main { public static void main(String[] args) { List<String> list = new ArrayList<String>(); list.add("s1"); list.add("s2"); list.add(null); list.add("s3"); list.add(null); list.add("s4"); println("Items:"); list.forEach(item -> println(item)); // Remove null refs println("Items (after nulls removed):"); boolean useJava8removeIf = false; if (useJava8removeIf) { println("Using Java8 removeIf method with predicate."); list.removeIf(Objects::isNull); } else { println("Using our own helper."); list = ListHelper.removeNullReference(list); } list.forEach(item -> println(item)); } static void println(String msg) { System.out.println(msg); } } 

removeAll没有为我工作。 相反,我创build了新的列表:

 new ArrayList<E>(list); 

就那么简单。