I'm trying to write
public static Comparable<? extends Comparable> getMax (ArrayList <? extends Comparable> list)
and I recieve an exception
Comparable is a raw type. References to generic type Comparable should be
parameterized
what can I do? I want recieve a collection and return an varaiable who implement the interface
If you want to find the max value in a list, why do you return a Comparable? Returning T where T is the type of object that the list stores is much better.
In addition, wildcards should not be used here. If you write your method like this:
public static Comparable<? extends Comparable> getMax (ArrayList <? extends Comparable> list)
then the client code can pass ArrayList<Integer> and you can return a String which makes no sense at all.
To avoid that kind of situation, I suggest you to use a generic type T
public static <T extends Comparable<T>> T getMax (ArrayList<T> list) {
return list.stream().max(Comparable::compareTo).orElse(null);
}
Related
I'm looking for how to pass as a parameter of a method a linkedList of a type which implements the Comparable interface.
public static void mergeSort(LinkedList<Comparable> list){}
I tried that but when I pass a primitive type such as Integer as a parameter it doesn't work.
If someone have an idea ?
Simply let the compiler know that the input type T extends Comparable<T>.
public static <T extends Comparable<T>> void mergeSort(final LinkedList<T> list)
I would not use the ?, which is a wildcard and represents an unknown type.
Explicitly specifying the generic type is always better (see this question).
Define a type parameter, and use that type parameter as the element type:
public static <C extends Comparable<? super C>> void mergeSort(LinkedList<C> list){}
You need to specify a bound parameter:
public static <T extends Comparable<? super T>> void mergeSort(LinkedList<T> list){}
This is taken from the method sort.
Say I have a class like this:
class OrderedFoo<T> {
public OrderedFoo(Comparator<? super T> comparator) {
//Do something
}
}
I could use this for non-comparable objects as the type parameter is not required to implement Comparable.
I could also use this for comparable objects, making use of Comparator#naturalOrder.
Example:
OrderedFoo<Watchable> nonComparable = new OrderedFoo<>((a, b) -> foo());
OrderedFoo<String> comparable = new OrderedFoo<>(Comparator.naturalOrder());
However, it gets somewhat tedious to have to specify a default comparator for comparable types. Is it possible to write a constructor with type parameters that will only accept a comparable type?
//Like this
public <???> OrderedFoo() {
this(Comparator.naturalOrder());
}
I tried <T extends Comparable<? super T>> but I get
(java.util.Comparator<? super T>)
in OrderedFoo cannot be applied to
(java.util.Comparator<T>)
Is this possible with a constructor?
You can't do this directly with a constructor, because that constructor has to be applicable to all types; but you want it only to work for Comparable types.
Use a static factory method with a suitably-constrained type variable:
public static <T extends Comparable<T>> OrderedFoo<T> naturalOrder() {
return new OrderedFoo<>(Comparator.naturalOrdering());
}
I have similar kind of two methods for different types of arguments.
1. For java.util.Set
public static <T> List<? super T> consumeSet(Set<? extends T> collection){
return null;
}
2. For java.util.List BR>
public static <T> List<? super T> consumeList(List<? extends T> collection){
return null;
}
I want to implement one common method which consumes only implements of List or Set but not Map. I am trying below mentioned method signature. Is it the right way to do this? If not, can anyone suggest me the right way? Thanks.
public static <T,V extends Set<T> & List<T>> List<? super T> consumeListAndSetButNotMap(V collection){
return null;
}
You can use the shared Collection interface. That won't accept Map.
While I was trying to solve exercise from generics tutorial Q&A My answers were slightly different
My Answers
public static <T extends Comparable<? super T>>
T max(List<? extends T> list, int begin, int end) //Option1
public static <T extends Comparable<T>>
T max(List<? extends T> list, int begin, int end) //Option2
from quoted answer below
So My question is
Option1 :Would it make any difference if T extends Object & Comparable<? super T> is replaced with T extends Comparable<? super T>. Isn't extends Object implicit ?
Option2 :Would it make any difference if Comparable<? super T> is replaced with Comparable<T> ? if so How ?
Eclipse code completion creates local variable List<? extends Comparable<? super Comparable<? super T>>> list; on Ctrl+1 max(list, 1, 10); which is bit lengthy. How to Define a classes (hierarchy) that extends Comparable<? super T> , create list and add instances to the list and invoke below method ? Basically I want to know how to invoke max() after adding class instances A or B into a list where class B extends A
Write a generic method to find the maximal element in the range
[begin, end) of a list.
Answer:
import java.util.*;
public final class Algorithm {
public static <T extends Object & Comparable<? super T>>
T max(List<? extends T> list, int begin, int end) {
T maxElem = list.get(begin);
for (++begin; begin < end; ++begin)
if (maxElem.compareTo(list.get(begin)) < 0)
maxElem = list.get(begin);
return maxElem;
}
}
Would it make any difference if Comparable<? super T> is replaced with Comparable<T> ? if so How ?
Remember that Comparables are always consumers, i.e., a Comparable<T> consumes T instances, so it should always be preferrable to use Comparable<? super T> instead of Comparable<T> (Quoting - PECS). It would make difference in case you are comparing a type whose super class implements a Comparable<SuperType>. Consider the following code:
class Parent implements Comparable<Parent> {
protected String name;
#Override
public int compareTo(Parent o) {
return this.name.compareTo(o.name);
}
}
class Child extends Parent {
public Child(String name) {
this.name = name;
}
}
Now if you give your type parameter as T extends Comparable<T>, you won't be able to call that method for List<Child>, as Child does not implement Comparable<Child> but Comparable<Parent>:
public static <T extends Comparable<T>> T max(List<? extends T> list, int begin, int end) {
...
}
public static void main(String[] args) {
List<Child> list = new ArrayList<Child>();
max(list, 0, 2); // Error with current method. Child does not implement Comparable<Child>
}
Hence the type parameter bounds should be T extends Comparable<? super T>.
Note that, you can't change your Child class to:
class Child extends Parent implements Comparable<Child>
because in that case, Child class would extend from different instantiation of same generic type, which is not allowed.
Would it make any difference if T extends Object & Comparable<? super T> is replaced with T extends Comparable<? super T>. Isn't extends Object implicit ?
Well, there is a difference between the two bounds. In the 1st bound, the erasure of the type parameter is Object, whereas in the 2nd bound, the erasure is Comparable.
So, without Object bound, your code will compile to:
public static Comparable max(List list, int begin, int end)
The issue might come when you are generifying the legacy non-generic code. It's neccessary to give Object also as upper bound to avoid breaking the Byte Code compatibility. You can read more about it on this link: Angelika Langer - Programming Idioms
It looks like there are more wildcards than necessary. I'll probably go with
public static <T extends Comparable<? super T>>
T max(List<T> list, int begin, int end)
An even more constrained version:
public static <T extends C, C extends Comparable<C>>
T max(List<T> list, int begin, int end)
i.e. T must have a super type that is comparable to itself. For example T cannot be Foo
class Foo implements Comparable<Object>
Foo does not make sense anyway; a Comparable can only be meaningfully compared to its own kind. The clause C extends Comparable<C> acknowledges that fact.
I have this interface
public interface IDataPoint<T> extends Comparable<T> {
public T getValue();
}
and this implementation...
public class IntegerDataPoint implements IDataPoint<Integer> {
// ... some code omitted for this example
public int compareTo(Integer another) {
// ... some code
}
}
and another class...
public class HeatMap<X extends IDataPoint<?> {
private List<X> xPoints;
}
Now I would like to use Collections.max (and similar) on the xPoints list, but that does not work, probably because I got my generics all messed up.
Any suggestions how this could be solved (without a Comparator)?
Collections.max(xPoints);
gives me this error:
Bound mismatch: The generic method max(Collection<? extends T>) of type Collections is not applicable for the arguments (List<X>). The inferred type X is not a valid substitute for the bounded parameter <T extends Object & Comparable<? super T>>
The problem is that Collections.max(Collection<? extends T>) wants the T's to be comparable to themselves not some other type.
In your case IntegerDataPoint is comparable to Integer, but not IntegerDataPoint
You cannot easily fix this because IntegerDataPoint is not allowed to implement Comparable<Integer> and Comparable<IntegerDataPoint> at the same time.