Understanding: public static <T> int max(List<T> list, Comparator<? super T> c) please

StackOverflow https://stackoverflow.com/questions/19503809

  •  01-07-2022
  •  | 
  •  

Question

Im supposed to make a method that returns the max value of any list, I guess this is a generic method. But I dont understand the parameters, could anyone please explain me? Also I made a iterator that i will use in the solution to run through the list, but when i make a instance of the iterator this method gives me the following error: "#nameofclass can not be referenced from a static context", then how do I make a instance here? ( its supposed to be static for some reason) I would appreciate any help!

public static <T> int maks(List<T> list, Comparator<? super T> c)
  {
    // return max in a list
  }
Was it helpful?

Solution

The following is a pretty typical generic method declaration:

public static <T> int max(List<T> list, Comparator<? super T> c) {
  :
  :
}

There are two overall kinds of generic declarations: 1) generic class/interface, and 2) generic method. Once you're comfortable with these two idioms, you're well on your way to having a good understanding of generics. The raw type declaration for this is:

public static int max(List list, Comparator c) {
  :
  :
}

The raw type declaration makes it easy to see that this method returns a value to its caller of type int. The method accepts two parameters: a List instance and a Comparator instance.

The trouble with the raw type declaration is that it is not safe. Why? Because both List<E> and Comparator<T> are generic classes that have been defined with a formal generic type parameter. If you use a generic class, but then don't specify its parameter (as in the declaration above) you lose all the type safety and expressiveness that generics provide for you.

A generic method is characterized by the following method:

public <T> MyType myMethodName( /* parameters */) { ... }

Notice that a generic method is declared with its type parameters in the method declaration and that the type parameters come immediately before the return type. This is standard.

In this case <T> indicates an unbounded type parameter for your method. Wherever T appears in your method, the actual type parameter passed to your method will take the place of T. It is common, but not necessary, to make the method parameters depend upon T (but T can appear anywhere inside the method body that a type declaration can appear -- with some exceptions necessitated by type erasure).

In your example, the parameters list is ...

(List<T> list, Comparator<? super T> c)

The first parameter specified that the instance list passed to your method will have the type List. Because T is the generic method type parameter listed in your method declaration, you can imagine that it is substituted for the actual type parameter that was passed to your method, eg. List<String> list.

The second parameter is a bit more complex. It is a bounded wildcard type parameter. The sematics for ? are "any type" and the semantics for super are "any class that is the same class or a super class of". Therefore the second parameter reads as "any type that is the same type or a super type of the actual type parameter T that was passed to your method."

There is a mnemonic that is apt for bounded wildcard types: PECS. Producer extends, Consumer super. Comparators are always consumers of their instances, and so the right way to specify them in a parameter list is as shown in your method declaration.

OTHER TIPS

You have List list and Comparator c, so why not just:

Collections.max(list, c);

-it will return max element in a List or any other Collection.

Though I don't understand why you want to return int when looking for max value in a generic list -maybe you're looking for its' index?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top