Существует ли стандартная реализация Java List, которая не позволяет добавлять к ней значение null? - PullRequest
24 голосов
/ 22 июня 2011

Скажем, у меня есть List, и я знаю, что никогда не хочу добавлять null к нему.Если я добавляю ноль к нему, это означает, что я делаю ошибку.Поэтому каждый раз, когда я в противном случае позвонил бы list.add(item), я бы вместо этого позвонил if (item == null) throw SomeException(); else list.add(item);.Есть ли существующий класс List (может быть, в Apache Commons или что-то в этом роде), который делает это для меня?

Аналогичный вопрос: Помощник для удаления пустых ссылок в списке Java? но я нене хочу удалять все нули, я хочу убедиться, что они никогда не будут добавлены в первую очередь.

Ответы [ 7 ]

25 голосов
/ 27 июня 2011

Осторожно - несколько ответов здесь утверждают, что решили вашу проблему, обернув список и отметив add и addAll, но они забывают, что вы также можете добавить к List через listIterator,Трудно получить правильный ограниченный список, поэтому Guava имеет Constraints.constrainedList, чтобы сделать это за вас.

Но прежде чем посмотреть на это, сначала подумайте, нужен ли вам только список неизменный , в этом случае ImmutableList Гуавы все равно выполнит для вас эту нулевую проверку.И в случае, если вы вместо этого можете использовать одну из реализаций JDK Queue, она тоже это сделает.

(Хороший список недействительных коллекций: https://github.com/google/guava/wiki/LivingWithNullHostileCollections)

16 голосов
/ 22 июня 2011

Использование коллекции Apache Commons:

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

При добавлении нуля в этот список выдается IllegalArgumentException.Кроме того, вы можете поддержать его любой реализацией List, которая вам понравится, и при необходимости вы можете добавить больше предикатов для проверки.

То же самое существует для коллекций в целом.

Использование Google Guava:

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

При добавлении нуля в этот список выдается NullPointerException.

5 голосов
/ 22 июня 2011

AFAIK, в JDK нет стандартной реализации.Однако спецификация Collection говорит, что исключение NullPointerException должно создаваться, когда коллекция не поддерживает значения NULL.Вы можете использовать следующую оболочку для добавления функциональности в любую коллекцию (вам придется реализовать другие методы коллекции, чтобы делегировать их в упакованный экземпляр):

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);
    }
    ...
}
1 голос
/ 22 июня 2011

Вы можете сделать это, просто обернув экземпляр List и предоставив проверенный на ноль метод add.Другими словами, у вашего класса будет просто пара методов и внутренняя переменная.

Если вам нужна полная функциональность списка, вы можете рассмотреть Guava (раньше это был Google Collections) ForwardingList .

Другой подход - просто расширить список, ноГвоздь в том, что вам нужно переопределить add и addAll.

Интересно, что в guava есть standardAddAll , который можно использовать как реализацию addAll, которая решаетНаименьшая часть проблемы.

1 голос
/ 22 июня 2011

Хотя эта проблема вроде «делегат», с подклассами намного проще, так как вы намерены наследовать почти все те же функции.

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);
  }
}
0 голосов
/ 22 июня 2011

Это должно работать

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

однако ошибка в реализации addAll означает, что вам нужно использовать следующее

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

и вы получите

list.add(null); threw java.lang.NullPointerException
list.addAll("", null); threw java.lang.NullPointerException
0 голосов
/ 22 июня 2011

попробуйте Collections.checkedList ().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...