Can I declare the following in Java?
public class NewIterator<E extends Comparable<? super E>> implements Iterator<E> {
NewIterator(Iterator<? extends E & Comparable<? super E>> iterator){
...
}
I am getting an error saying
Multiple markers at this line
- Incorrect number of arguments for type Iterator<E>; it cannot be parameterized with arguments <? extends E, Comparable<? super E>>
- Syntax error on token ",", ; expected
- Syntax error on token "&", , expected
- Syntax error on token ")", ; expected
By defining your class as
class NewIterator<E extends Comparable<? super E>> implements Iterator<E> {
you say that E has to implement Comparable<? super E>.
Now in the constructor you try to repeat that and allow subtypes of E.
NewIterator(Iterator<? extends E & Comparable<? super E>> iterator){
...
}
If you do just
public NewIterator(Iterator<? extends E> iterator) {
}
You should get what you want because E already defines that it's a type that implements the comparable interface.
Example
class IntegerNumber {}
class PositiveNumber extends IntegerNumber implements Comparable<IntegerNumber> {}
class OddPositiveNumber extends PositiveNumber {}
private NewIterator<PositiveNumber> newIterator;
void foo() {
Iterator<PositiveNumber> iterator = createIteratorFrom(
new PositiveNumber(1),
new OddPositiveNumber(7)
);
this.newIterator = new NewIterator(iterator);
}
If you use PositiveNumber in NewIterator<E extends Comparable<? super E>> you can replace E by PositiveNumber. So your constructor accepts Iterator<? extends PositiveNumber>. You can now create an iterator over any subclass of PositiveNumber but since that class inherits from PositiveNumber it must also inherit the Comparable<IntegerNumber> interface.
Related
Is it possible to do this in java without problems?
My IDE highlights my code as "Raw use of parameterized class 'Etat' " and "Unchecked call to 'add(E)' as a member of raw type 'java.util.ArrayList'"
My code :
public abstract class Etat<T extends Transition> {}
public abstract class Transition<E extends Etat> {}
Might you be looking for:
class Etat<E extends Etat<E, T>, T extends Transition<E, T>> {}
class Transition<E extends Etat<E, T>, T extends Transition<E, T>> {}
Then, you can do:
class MonEtat extends Etat<MonEtat, MaTransition> {}
class MaTransition extends Transition<MonEtat, MaTransition> {}
allowing the two types to know each other through their type parameter. For instance, if you declare:
class Etat<E extends Etat<E, T>, T extends Transition<E, T>> {
abstract E apply(T transition);
}
You can then be assured that
MonEtat e = ...;
e = e.apply(new MaTransition()); // compiles, and knows that MonEtat is returned
class A<T extends Comparable<? super T>> {
Supplier<T> supp;
A(Supplier<T> supp) {
this.supp = supp;
}
static <T extends Comparable<? super T>> A<T> of(Supplier<T> supp) {
return new A<T>(supplier);
}
<U> A<U> map(Function<? super T, ? extends U> mapper) {
return A.of(() -> mapper.apply(this.supp.get()));
}
}
When I compile, I get error saying:
type argument U is not within bounds of type-variable T
where U,T are type-variables:
U extends Object declared in method <U>map(Function<? super T,? extends U>)
T extends Comparable<? super T> declared in class A
I feel that I need to make U in mapper extend something, but I am not really sure how, I have tried U extends Comparable, etc. but they don't work.
Consider the following code:
public final class Algorithm {
public static <T extends Comparable<? super T>>
T max(List<? extends T> list, int begin, int end)
{
// ...
}
}
Is the List<? extends T> list parameter declaration equal to List<? extends Comparable<? super T>> list?
There is a very slight difference.
List<? extends T> means
a List of objects of an unknown type that is either T or a subclsss of T
List<? extends Comparable<? super T>> means
a List of objects of an unknown type that is either Comparable<? super T> or an implementation of Comparable<? super T>.
Let's consider this class hierarchy: A and B are unrelated classes that both implement Comparable<A> and are both final. Yes, I know this situation is contrived.
If, from the return value, T is inferred to be A, you can only pass a List<A> to a parameter of type List<? extends T>. However, you can pass a List<A>, as well a List<B> to a parameter of type List<? extends Comparable<? super T>>.
Here is an example demonstrating my point:
public static void main(String[] args) {
List<A> aList = Collections.singletonList(new A());
List<B> bList = Collections.singletonList(new B());
A a = f(aList);
A b = f(bList); // doesn't compile
A c = g(bList);
A d = g(bList);
}
public static <T extends Comparable<? super T>> T f(List<? extends T> list) {
return null;
}
public static <T extends Comparable<? super T>> T g(List<? extends Comparable<? super T>> list) {
return null;
}
final class A implements Comparable<A> {
#Override
public int compareTo(A o) {
return 0;
}
}
final class B implements Comparable<A> {
#Override
public int compareTo(A o) {
return 0;
}
}
In reality though, very rarely do things like class B implements Comparable<A> happen, so for the most part, the two types in question are the same.
So I have an interface Foo is constructed like:
public interface Foo<T extends Comparable<? super T>>
and I'm trying to implement Foo in my class bar like:
public class Bar<T> implements Foo<T>
but I get getting the error type argument T#1 is not within bounds of type-variable T#2
but when I try to implement Foo as:
public class Bar<T> implements Foo<T extends Comparable<? super T>>
I get > expected and <identifier> expected
Your syntax is a bit off. Try moving the bounds to the declaration of T as in this:
public class Bar<T extends Comparable<? super T>> implements Foo<T> {
...
}
I am trying to extend a version of TreeMap into a subclass to index words more efficiently, but I am unsure what the correct syntax is. The class definition for the treemap looks like this
public class MyTreeMap<K extends Comparable<? super K>,V> extends AbstractMap<K,V> {
Extending the class in the most straightforward way
public class TreeMapIndexer<K> extends MyTreeMap<K,LinkedList<Integer>> {
yields the error
"Bound mismatch: The type K is not a valid substitute for the bounded parameter > of the type MyTreeMap".
I tried
public class TreeMapIndexer<K> extends
MyTreeMap<K extends Comparable<? super K>, LinkedList<Integer>> {
instead, but that yields the compiler error "Syntax error on token "extends", , expected". The erroneous extends is in the "".
I found another thread (Generic Generics: "Syntax error on token "extends", , expected") with the same error message. It appears to be a slightly different situation than mine, but I tried
public class TreeMapIndexer<K> extends
MyTreeMap<K, K extends Comparable<? super K>, LinkedList<Integer>> {
which yields exactly the same "Syntax error on token "extends", , expected" compiler message.
class MyTreeMap<K extends Comparable<? super K>, V>
extends AbstractMap<K, V>
So K is declared with a bound of extends Comparable<? super K>. You just need to redeclare that same bound on the subclass.
class TreeMapIndexer<K extends Comparable<? super K>>
extends MyTreeMap<K, LinkedList<Integer>>
Otherwise you are attempting to declare the subtype as not having the restriction which is the compilation error 'bound mismatch'.
What you tried was almost right, the bound just needed to be in the generic type declaration, not the arguments (passed along) to the superclass.