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

时间:2009-08-06 15:13:01

标签: java collections

给出以下列表:

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”(非空引用)。

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

6 个答案:

答案 0 :(得分:110)

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

答案 1 :(得分:9)

Java 8添加了Collection.removeIf(Predicate),删除了与谓词匹配的所有元素,因此您可以使用

从列表(或任何集合)中删除所有出现的$( ".container" ).append( $( "div" ) );
null

使用java.util.Objects.isNull作为list.removeIf(Objects::isNull);

如果您愿意,也可以使用Predicate; the difference is very minor

答案 2 :(得分:3)

如果您可以控制List的实例化,那么您可以通过编写自定义List实现来阻止添加空值,例如:

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

答案 3 :(得分:3)

Don的方法的一个缺点是它从ArrayList延伸。现在这可能已经足够好了,但是当您想要使用不同的List实现时会发生什么?你可以制作一个NoNullsLinkedList和一个NoNullsCopyOnWriteArrayList等,但最后你会得到一些只在extends子句中有所不同的小类。创建一个不接受空值的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 );
  }
}

这是更多代码,但现在您可以灵活地在创建对象时选择List实现。

可能的问题是您仍然可以将null插入基础List对象中。唐的方法没有相同的限制。

答案 4 :(得分:1)

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

list.removeIf(Objects::isNull);

另一方面,如果您正在寻找一个简单的实现来了解它是如何完成的,例如返回新的非空列表的辅助类,您可以查看以下代码。它也可以接受泛型类型,为了简单起见,我在helper类中使用了相同的集合类型(如问题中所示)。

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

答案 5 :(得分:-2)

removeAll对我不起作用。相反,我创建了新列表:

new ArrayList<E>(list);

这很简单。