Подтвердить что ты не робот

Существует ли стандартная реализация Java List, которая не позволяет добавлять к ней нуль?

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

Добавление значения null в этот список вызывает IllegalArgumentException. Кроме того, вы можете поддержать его с помощью любой реализации списка, которая вам нравится, и при необходимости вы можете добавить дополнительные предикаты для проверки.

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

Использовать Google Guava:

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

Добавление значения null в этот список вызывает NullPointerException.

Ответ 3

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

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

Ответ 4

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

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

Другой подход состоит в том, чтобы просто расширить List, но в gotcha есть то, что вам нужно переопределить как add, так и addAll.

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

Ответ 5

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

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

Ответ 6

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

Ответ 7

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

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