In addition to implementing a Bag & List for an assignment, the next step is to create an ordered version. A requirement is to specify the parametric interface OrderedCollection with the correct type parameters and constraints. My problem is with implementing it.
An interface Collection <E> exists and is defined as
public interface Collection<E> extends Iterable<E>{
public void add(E e);
public void remove(E e);
public boolean contains(Object e);
public void clear();
public int size();
public boolean isEmpty();
public Object[] toArray();
}
It is implemented by the classes
public class UnorderedList<E> implements Collection<E>
public class UnorderedBag<E> extends UnorderedList<E> implements Collection<E>
I have the structures working, and am now trying to implement the sorted version. To do this and satisfy part of the requirements, I created OrderedCollection as
public interface OrderedCollection <E extends Comparable<E>> {
public int compareTo(E e);
}
because it is extending the methods already defined in Collection, and the only new functionality required is a compareTo() method.
However, when I try to implement OrderedList by the declaration
public class OrderedList<E> extends UnorderedList<E> implements OrderedCollection<E>
I get an error stating that
Bound mismatch: The type E is not a valid substitute for the bounded parameter <E
extends Comparable<E>> of the type OrderedCollection<E>
As I understand the error message, I need to specify a parameter type that is a valid substitute for the one given in the interface declaration. However, I've tried
OrderedCollection<E extends Comparable<E>>
as the implements declarer, but then I get a warning that a syntax error exists on extends.
How do I satisfy the requirements here?
In your declaration of the OrderedList class, the generic type of OrderedList needs to match the restriction that OrderedCollection expects.
public class OrderedList<E extends Comparable<E>>
extends UnorderedList<E>
implements OrderedCollection<E>
Related
I am new to java. I am just trying to pass Comparable<String> into a method parameter of generic type <E extends Comparable<E>> . I believe the meaning of <E extends Comparable<E>> is any object that extends Comparable. Please let me know how to pass Comparable<String> or any object that extends Comparable<String> and has an other object in it.
Compiler is giving me error The inferred type Compare<String> is not a valid substitute for the bounded parameter <E extends Comparable<E>>
Code:
public class Compare<T> implements Comparable<T>{
public int compareTo(T o) {
return 0; // Not worried about logic
}
}
class CompareTest{
public <E extends Comparable<E>>void testGeneric(E e){
System.out.println("Executed");
}
public static void main(String args[]){
Compare<String> compare = new Compare<String>();
CompareTest test = new CompareTest();
test.testGeneric(compare);
//The inferred type Compare<String> is not a valid substitute for the bounded
//parameter <E extends Comparable<E>>
}
}
E extends Comparable<E> means: a type E that is able to compare to other objects of the same type E.
But your Compare type doesn't qualify. It can't compare with another Compare. A Compare<T> can only compare itself to a T, and not to a Compare<T>, since it's declared as
public class Compare<T> implements Comparable<T>
It's quite hard to understand what you want to achieve with this Compare type.
Your method
public <E extends Comparable<E>> void testGeneric(E e){
expects a type E that is a sub type of Comparable<E>. But you are passing it a Compare<String> which is not a sub type of <Comparable<Compare<String>>, but a sub type of Comparable<String>.
You'll have to clarify what you are trying to do if you need more help.
The error in my IDE says:
Inferred type 'Compare<java.lang.String>' for type parameter 'E' is not within its bound;
should implement 'java.lang.Comparable<Compare<java.lang.String>>'
It seems that E is inferred as Compare<String> instead of String. To get E to be String, try this:
public <E extends Comparable<E>> void testGeneric(Comparable<E> e){
To define a class as being comparable, the generic parameter to Comparable must be the class itself:
public class MyComparable implements Comparable<MyComparable> {
public int compareTo(MyComparable o) {
return 0;
}
}
Applying that to your class, you get the following code (which compiles):
public static class Compare<T> implements Comparable<Compare<T>> {
public int compareTo(Compare<T> o) {
return 0; // Not worried about logic
}
}
class CompareTest {
public <E extends Comparable<E>> void testGeneric(E e) {
System.out.println("Executed");
}
}
public static void main(String[] args) {
Compare<String> compare = new Compare<String>();
CompareTest test = new CompareTest();
test.testGeneric(compare);
}
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.
Suppose I have the following interface:
public interface Interface<T extends Number>{
public Vector<Interface<T>> getVector();
}
and the following class implementing that interface:
public abstract class C<T extends Number> implements Interface<T>{
private Vector<C<T>> vector;
public Vector<Interface<T>> getVector(){ //errror
return this.vector;
}
}
Why is not legal returning a Vector<C<T>> meanwhile is legal ( obviously) returning a Vector<Interface<T>>. C is actually implementing Interface, so it should be possible, right? What am I missing?
EDIT:
why this work for non generics interface? Is this actually a generic related problem?
public interface Interface{
public Interface getVector();
}
public abstract class C implements Interface {
private C;
public Interface getVector(){ //errror
return this.c;
}
}
Because the Vector is explicitly made up of Interface<T>, not things that extend Interface<T>, I believe this would work if you changed the definition to
public Vector<? extends Interface<T>> getVector();
The problem is that for some V implements T or V extends T that Foo<V> is not a supertype of Foo<T>. The compiler does not test inheritance on the generic arguments unless you explicitly indicate that extension point.
Using Vector<? extends Interface<T>> means "allow any class that implements or extends Interface<T>, whereas Vector<Interface<T>> means a vector consisting only of Interface<T> items.
Perhaps it's more concrete to consider that List<Integer> is not an acceptable replacement for List<Number> despite Integer extending Number for precisely the same reason.
update:
I tested this and the following compiles without any errors or warnings
interface Interface<T extends Number>{
public Vector<? extends Interface<T>> getVector();
}
abstract class C<T extends Number> implements Interface<T>{
private Vector<C<T>> vector;
public Vector<? extends Interface<T>> getVector(){
return this.vector;
}
}
It's the way generics work. They are not "covariant": if you have class AClass and its subclass SubAClass, Vector<SubAClass> is not a subclass of Vector<A>. (Note however that SubAClass[] is a subclass of AClass[].)
EDIT:
The seemingly obvious:
public ArrayList<Object> blah() {
return new ArrayList<String>();
}
won't compile because ArrayList<String> is not a subclass ArrayList<Object>. So in your case you can't return a Vector<C<T>> instance for a Vector<Interface<T>>.
I tried to create an interface ISortableStack using <E extends comparable <E>> but I can't move forward. What does the following do?
<E extends Comparable<E>>
I've tried this, but it doesn't help.
<E extends Comparable<E>> means that E must be a type that knows how to compare to itself, hence, the recursive type definition.
public class Comparables {
static class User implements Comparable<User> {
#Override
public int compareTo(User user) {
return 0;
}
}
/**
* This class cannot be used with Collections.sort because an
* UncomparableUser is not comparable with itself. However, notice
* that you get no compiler error just for implementing
* Comparable<String>.
*/
static class UncomparableUser implements Comparable<String> {
#Override
public int compareTo(String user) {
return 0;
}
}
public static void main(String[] args) {
List<User> users = Arrays.asList(new User());
// Using this would cause a compiler error
// List<UncomparableUser> users = Arrays.asList(new UncomparableUser());
Collections.sort(users);
}
}
If you're asking what does this mean:
<E extends Comparable<E>>
It means that the class 'E' passed in must implement the Comparable interface.
The < and > characters are part of the "generic" syntax. The standard library is choke full of "generic" interfaces; take a look at the Set interface for an example.
I want to have an interface A parameterised by T A<T>, and also want every class that implements it to also implement Comparable (with T and its subtypes). It would seem natural to write interface A<T> extends Comparable<? extends T>, but that doesn't work. How should I do it then?
When Comparable<? extends T> appears it means you have an instance of Comparable that can be compared to one (unknown) subtype of T, not that it can be compared to any subtype of T.
But you don't need that, because a Comparable<T> can compare itself to any subtype of T anyway, e.g. a Comparable<Number> can compare itself to a Comparable<Double>.
So try:
interface A<T> extends Comparable<T> {
// ...
}
or
interface A<T extends Comparable<T>> extends Comparable<A<T>> {
// ...
}
depending on whether you need to be able to compare instances of T in order to implement your compareTo method.
If you use comparable you do not need to specify the possibility for subtypes in the compare function, it is by nature possible to pass in any subtype of an object X into a method that declared a parameter of class X. See the code below for more information.
public interface Test<T> extends Comparable<T> {
}
class TestImpl implements Test<Number> {
#Override
public int compareTo(final Number other) {
return other.intValue() - 128;
}
}
class TestMain {
public static void main(final String[] args) {
TestImpl testImpl = new TestImpl();
testImpl.compareTo(Integer.MIN_VALUE);
}
}