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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1239579/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 01:16:32  来源:igfitidea点击:

Helper to remove null references in a Java List?

javacollections

提问by Arthur Ronald

Given the following List:

鉴于以下列表:

List<String> list = new ArrayList<String>();

list.add("s1");
list.add("s2");
list.add(null);
list.add("s3");
list.add(null);
list.add("s4");

I need a helper class that removes null references. Something like:

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

SomeHelper.removeNullReference(list);

SomeHelper.removeNullReference(list);

such that the list only contains "s1", "s2", "s4", "s4" (non-null references).

这样列表只包含“s1”、“s2”、“s4”、“s4”(非空引用)。

What should I use to fulfill this requirement?

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

采纳答案by Michael Borgwardt

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

回答by Dónal

If you can control the instantiation of the Listthen you could prevent the nulls being added by writing a custom Listimplementation such as:

如果您可以控制 的实例化,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, you don't need to override addAllbecause the ArrayListimplementation thereof calls add.

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

回答by debaser

A drawback of Don's approach is that it extends from ArrayList. That may be good enough for now, but what happens when you want to use a different Listimplementation? You could make a NoNullsLinkedListand a NoNullsCopyOnWriteArrayList, etc, but then you wind up with a bunch of little classes that differ only in their extendsclause. It might be better to create a Listwrapper that doesn't accept null values. For example:

Don 方法的一个缺点是它从ArrayList. 现在这可能已经足够了,但是当您想使用不同的List实现时会发生什么?您可以创建 aNoNullsLinkedList和 aNoNullsCopyOnWriteArrayList等,但是您最终会得到一堆仅在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 );
  }
}

It's more code, but now you have the flexibility of choosing a Listimplementation when you create the object.

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

A possible problem is that you can still insert nulls into the underlying Listobject. Don's approach doesn't have the same limitation.

一个可能的问题是您仍然可以将nulls 插入到底层List对象中。Don 的方法没有相同的限制。

回答by Jeffrey Bosboom

Java 8 added Collection.removeIf(Predicate)that removes all elements matching the predicate, so you can remove all occurrences of nullfrom a list (or any collection) with

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

list.removeIf(Objects::isNull);

using java.util.Objects.isNullas a Predicate.

使用java.util.Objects.isNullPredicate

You can also use .removeIf(x -> x == null)if you prefer; the difference is very minor.

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

回答by omt66

I really like the Java 8's new concise solution, I believe you should use that whenever possible.

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

list.removeIf(Objects::isNull);

On the other side, if you are looking for a simple implementation to learn how it could be done, such as a helper class that returns new non-null list, you can take a look at the following code. It can also be made to accept generic types, for the sake of simplicity I used the same collection type (as in the question) in the helper class.

另一方面,如果您正在寻找一个简单的实现来了解它是如何完成的,例如返回新的非空列表的帮助类,您可以查看以下代码。它也可以接受泛型类型,为了简单起见,我在 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);
    }
}