是否有标准的 Java List 实现不允许向其添加 null?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6433478/
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-16 05:52:36  来源:igfitidea点击:

Is there a standard Java List implementation that doesn't allow adding null to it?

javalistcollectionsnull

提问by MatrixFrog

Say I have a Listand I know that I never want to add nullto it. If I am adding null to it, it means I'm making a mistake. So every time I would otherwise call list.add(item)I would instead call if (item == null) throw SomeException(); else list.add(item);. Is there an existing Listclass (maybe in Apache Commons or something) that does this for me?

假设我有一个List,我知道我永远不想添加null它。如果我向它添加 null ,则意味着我犯了一个错误。所以每次我会打电话时,list.add(item)我都会打电话给if (item == null) throw SomeException(); else list.add(item);. 是否有一个现有的List类(可能在 Apache Commons 或其他东西中)为我做这件事?

Similar question: Helper to remove null references in a Java List?but I don't want to remove all the nulls, I want to make sure they never get added in the first place.

类似问题:Helper to remove null references in a Java List?但我不想删除所有空值,我想确保它们永远不会被添加到首位。

回答by Jeremy

Although this problem sort of yells "delegate", it's much easier with subclassing since you intend to inherit almost all the same functionality.

尽管这个问题有点像“委托”,但是子类化要容易得多,因为您打算继承几乎所有相同的功能。

class MyList extends List {

  //Probably need to define the default constructor for the compiler

  public add(Object  item) {
    if (item == null) throw SomeException();
    else super.add(item);
  }    

  public addAll(Collection c) {
    if (c.contains(null)) throw SomeException();
    else super.addAll(c);
  }
}

回答by joeslice

You might do this by just wrapping an instance of a List and providing the null-checked add method. In other words, your class would just have a couple of methods and in inner variable.

您可以通过包装一个 List 的实例并提供空检查的 add 方法来做到这一点。换句话说,你的类只有几个方法和内部变量。

If you need the full functionality of a list, you might consider Guava's (used to be Google Collections) ForwardingList.

如果您需要列表的全部功能,您可以考虑使用 Guava 的(曾经是 Google Collections)ForwardingList

Another approach is to just extend List, but the gotcha there is that you need to override both addand addAll.

另一种方法是仅扩展 List,但问题是您需要同时覆盖addaddAll

Interestingly, guava has a standardAddAll, which can be used as the implementation of addAll, which solves at least part of the problem.

有趣的是,guava 有一个standardAddAll,可以作为addAll的实现,至少解决了部分问题。

回答by Ryan Gross

AFAIK, there is no standard implementation available in the JDK. However, the Collection specsays that NullPointerException should be thrown when a collection does not support nulls. you can use the following wrapper to add the functionality to any Collection (you'll have to implement the other Collection methods to delegate them to the wrapped instance):

AFAIK,JDK 中没有可用的标准实现。但是,Collection 规范说,当集合不支持空值时,应该抛出 NullPointerException。您可以使用以下包装器将功能添加到任何 Collection(您必须实现其他 Collection 方法以将它们委托给包装的实例):

class NonNullCollection<T> implements Collection<T> {

    private Collection<T> wrapped;
    public NonNullCollection(Collection<T> wrapped) {
        this.wrapped = wrapped;
    }
    @Override
    public void add(T item) {
        if (item == null) throw new NullPointerException("The collection does not support null values");
        else wrapped.add(item);
    }
    @Override
    public void addAll(Collection<T> items) {
        if (items.contains(null)) throw new NullPointerException("The collection does not support null values");
        else wrapped.addAll(item);
    }
    ...
}

回答by mP.

try Collections.checkedList().

试试 Collections.checkedList()。

回答by Peter Lawrey

This should work

这应该工作

List<String> list = Collections.checkedList(new ArrayList<String>(), String.class);
try {
    list.add(null);
    throw new AssertionError("Expected a NPE");
} catch (NullPointerException expected) {
    System.out.println("list.add(null); threw "+expected);
}
try {
    List<String> list2 = Arrays.asList("", null);
    list.addAll(list2);
    throw new AssertionError("Expected a NPE");
} catch (NullPointerException expected) {
    System.out.println("list.addAll(\"\", null); threw " + expected);
}

however a bug in the addAll implementation means you need to use the following

但是 addAll 实现中的错误意味着您需要使用以下内容

List<String> list = Collections.checkedList(
   Collections.checkedList(new ArrayList<String>(), String.class), String.class);

and you get

你得到

list.add(null); threw java.lang.NullPointerException
list.addAll("", null); threw java.lang.NullPointerException

回答by Fabian Barney

Use Apache Commons Collection:

使用 Apache Commons 集合:

ListUtils.predicatedList(new ArrayList(), PredicateUtils.notNullPredicate());

Adding null to this list throws IllegalArgumentException. Furthermore you can back it by any List implementation you like and if necessary you can add more Predicates to be checked.

将 null 添加到此列表会引发IllegalArgumentException. 此外,您可以通过任何您喜欢的 List 实现来支持它,如有必要,您可以添加更多要检查的谓词。

Same exists for Collections in general.

一般情况下,集合也是如此。

Use Google Guava:

使用谷歌番石榴:

Constraints.constrainedList(new ArrayList(), Constraints.notNull())

Adding null to this list throws NullPointerException.

将 null 添加到此列表会引发NullPointerException.

回答by Kevin Bourrillion

Watch out -- several answers here are claiming to solve your problem by wrapping a list and checking in addand addAll, but they're forgetting you can also add to a Listvia its listIterator. It's challenging to get a constrained list right, which is why Guava has Constraints.constrainedListto do it for you.

注意——这里的几个答案声称可以通过包装一个列表并签入addand来解决您的问题addAll,但他们忘记了您也可以List通过它的listIterator. 获得正确的受约束列表具有挑战性,这就是 Guava 必须Constraints.constrainedList为您做的原因。

But before looking at that, first consider whether you only need an immutablelist, in which case Guava's ImmutableListwill do that null checking for you anyway. And in the off chance that you can use one of the JDK's Queueimplementations instead, that'll do it too.

但是在查看之前,首先考虑您是否只需要一个不可变列表,在这种情况下,GuavaImmutableList无论如何都会为您进行空值检查。如果您可以改用 JDK 的Queue实现之一,那也可以这样做。

(Good list of null-hostile collections: https://github.com/google/guava/wiki/LivingWithNullHostileCollections)

(空敌对集合的好列表:https: //github.com/google/guava/wiki/LivingWithNullHostileCollections