帮助删除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);
就那么简单。