В чем смысл коллекции <?>

Я читал Effective Java, и я столкнулся с неограниченным типом Collection <?>. Тем не менее, чтение заставило меня поверить, что вы не можете поместить какие-либо элементы, кроме null, в экземпляр Collection<?>.

Итак, мой вопрос таков: какова цель создания экземпляра Collection<?>, когда мы можем вставлять элементы null, поскольку это кажется бессмысленным. Я пытался понять эту концепцию, но это, похоже, не имеет большого смысла. Любая помощь будет высоко оценена.

Ответ 1

Collection<?> позволяет создавать, среди прочего, методы, которые принимают любой тип Collection в качестве аргумента. Например, если вам нужен метод, который возвращает true, если любой элемент в Collection равен некоторому значению, вы можете сделать что-то вроде этого:

public boolean collectionContains(Collection<?> collection, Object toCompareTo) {
    for (Object o : collection) {
        if (toCompareTo.equals(o)) return true;
    }
    return false;
}

Этот метод может быть вызван любым типом Collection:

Set<String> strings = loadStrings();
collectionContains(strings, "pizza");

Collection<Integer> ints = Arrays.toList(1, 2, 3, 4, 5);
collectionContains(ints, 1337);

List<Collection<?>> collections = new ArrayList<>();
collectionContains(collections, ILLEGAL_COLLECTION);

Ответ 2

Рассмотрим следующий метод Util из документации

Следующий метод показывает вам, как использовать Iterator для фильтрации произвольной коллекции, то есть перемещать коллекцию, удаляя определенные элементы.

static void filter(Collection<?> c) {
    for (Iterator<?> it = c.iterator(); it.hasNext(); )
        if (!cond(it.next()))
            it.remove();
}

Этот простой фрагмент кода является полиморфным, что означает, что он работает для любого Collection независимо от реализации.

Ответ 3

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

Это действительно полезно, если у вас есть метод, по которому вы хотите передать все типы коллекций, например:

void printCollection(Collection<?> c) {
    for (Object e : c) {
        System.out.println(e);
    }
}

Взгляните на документацию Oracle о диких картах, поскольку она очень исчерпывающая.

Ответ 4

Collection является самой низкой абстракцией всех Lists и Sets. Хорошо использовать как самую низкую абстракцию, которую вы можете использовать, потому что она дает вам больше гибкости в будущем, а ваш код более надежный, потому что он может обрабатывать все Lists или Sets или другие реализации, которые даже не должны быть реализовано еще.

Ну, коллекция как-то эквивалентна Collection<Object>. Это просто означает, что общий тип объектов, хранящихся в Collection, неизвестен, или вы можете использовать самую низкую абстракцию любого объекта, который является Object. В этом случае вы можете помещать в Collection любой объект, даже смешивая его с разными типами. Но вы должны быть осведомлены о том, чтобы привести его в правильный тип во время выполнения, потому что вы не указали, какой тип объекта хранится в вашей коллекции. Таким образом, коллекция не может отнести объект к соответствующему типу для вас, вы должны сделать это самостоятельно. Чтобы распознать правильный тип, во время выполнения вы должны использовать Object instanceof SomeOtherClass или Class.isAssignableFrom(Class).

Также Collection не реализует метод get(), но вы можете получить Iterator и получить объект из коллекции таким образом.