Подпись метода Collections.min/max

В Java класс Наборов содержит следующий метод:

public static > T min(Collection c)

Его подпись известна за его усовершенствованное использование дженериков, так что это упоминается в Java, вкратце заказывают и в официальном Учебном руководстве по Дженерикам Sun.

Однако я не мог найти убедительный ответ на следующий вопрос:

Почему формальный параметр типа Collection, вместо Collection? Каково дополнительное преимущество?

15
задан Marco 25 May 2010 в 18:14
поделиться

5 ответов

Одно из преимуществ ? заключается в том, что он запрещает добавление элементов в коллекцию

5
ответ дан 1 December 2019 в 04:00
поделиться

Вывод типа - сложная тема, и я признаю, что Я не так уж много знаю об этом. Однако рассмотрим этот пример:

public class ScratchPad {
   private static class A implements Comparable<A> {
     public int compareTo(A o) { return 0; }
   }
   private static class B extends A {}
   private static class C extends B {}

   public static void main(String[] args)
   {
     Collection<C> coll = null;
     B b = Scratchpad.<B>min(coll);
   }

   public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> c)  {
     return null;
   }

   //public static <T extends Object & Comparable<? super T>> T min(Collection<T> c) {
   //  return null;
   //}
}

Учтите, что первая сигнатура min () позволяет вызову компилироваться, а вторая - нет. Это не очень практичный пример, так как нужно спросить, почему я должен явно вводить метод в , но, возможно, есть неявный вывод, где B будет предполагаемый тип.

6
ответ дан 1 December 2019 в 04:00
поделиться

Я думаю, что на самом деле это не дает вам ничего большего для этого метода, однако это хорошая привычка, которую нужно выработать, когда T является частью класса, а не просто статическим методом.

Они включают его сюда, чтобы он стал новой конвенцией, по которой каждый generic должен быть расширен на ?

Класс T должен следовать PECS: Что такое PECS (Producer Extends Consumer Super)?

Но статическому методу это не нужно (по крайней мере, параметрам, возвращаемое значение должно быть всегда)

4
ответ дан 1 December 2019 в 04:00
поделиться

Основываясь на комментариях, которые я добавил к ответу Марка, если у вас есть что-то вроде

class Play {
    class A implements Comparable<A> {
        @Override
        public int compareTo(A o) {
            return 0;
        }
    }

    class B extends A {
    }

    class C extends A {
    }

    public static <T extends Object & Comparable<? super T>> T min(
            Collection<? extends T> c) {
        Iterator<? extends T> i = c.iterator();
        T candidate = i.next();

        while (i.hasNext()) {
            T next = i.next();
            if (next.compareTo(candidate) < 0)
                candidate = next;
        }
        return candidate;
    }

    public static List<? extends A> getMixedList() {
        Play p = new Play();
        ArrayList<A> c = new ArrayList<A>();
        c.add(p.new C());
        c.add(p.new B());
        return c;
    }

    public static void main(String[] args) {
        ArrayList<A> c = new ArrayList<A>();
        Collection<? extends A> coll = getMixedList();
        A a = Play.min(coll);
    }
}

Ясно, что min возвращает объект типа A (фактическая подпись - A Play.min (Коллекция c) ). Если вы оставите min (Collection ) без расширяемой части, тогда Play.min (coll) будет иметь следующую подпись ? расширяет A Play.min (Collection c) , что не так ясно.

1
ответ дан 1 December 2019 в 04:00
поделиться

Это необходимо для поддержки устаревшей сигнатуры метода в Java 1.4 (и ранее).

До Java 5 подпись для этих методов была

public static Object min ( Collection c );

С несколькими границами правила стирания делают первую привязку необработанным типом метода, поэтому без Object & подпись будет

public static Comparable min ( Collection c );

и устаревший код сломается.

Это взято из книги О'Рейли по обобщениям и коллекциям Java, глава 3.6

2
ответ дан 1 December 2019 в 04:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: