Signature of Collections.min/max method

余生颓废 提交于 2019-12-30 05:47:09

问题


In Java, the Collections class contains the following method:

public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> c)

Its signature is well-known for its advanced use of generics, so much that it is mentioned in the Java in a Nutshell book and in the official Sun Generics Tutorial.

However, I could not find a convincing answer to the following question:

Why is the formal parameter of type Collection<? extends T>, rather than Collection<T>? What's the added benefit?


回答1:


One benefit of the ? is that it prohibits additions of items to the Collection




回答2:


Type inference is a tricky topic that I'll admit that I don't know that much about. However, examine this example:

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

Consider that the first signature of min() allows the call to compile whereas the second does not. This isn't a very practical example, since one must ask why I would be explicitly typing the method to <B>, but perhaps there is an implicit inference where B would be the inferred type.




回答3:


I think it actually doesn't give you anything more for this method, however its a good habit to get into when T is part of the class and not just a static method.

They are including it here so it can become the new convention where every generic should be extended by ?

A class of T should follow PECS: What is PECS (Producer Extends Consumer Super)?

But a static method doesn't need to (at least the parameters, the return value should always)




回答4:


This is to support a legacy signature of the method in Java 1.4 ( and before ).

Prior to Java 5 the signature for these methods was

public static Object min ( Collection c );

With multiple bounds the erasure rules make the first bound the raw type of the method, so without Object & the signature would be

public static Comparable min ( Collection c );

and legacy code would break.

This is taken from O'Reilly's Java Generics and Collections book, chapter 3.6




回答5:


Building on the comments I put on Mark's answer, if you have something like

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

It's clearer that min returns an object of type A (the actual signature is <A> A Play.min(Collection<? extends A> c) ). If you leave min(Collection<T>) without the extends part then Play.min(coll) will have the following signature <? extends A> ? extends A Play.min(Collection<? extends A> c) which isn't as clear.



来源:https://stackoverflow.com/questions/2907297/signature-of-collections-min-max-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!