Can someone please help me understand why this Java code doesn't compile?
The idea is that A is a tree-like class for a type T that takes a collection of children at construction.
Then I define an extension B of A that specializes T for Pair<R,R>.
class A<T> {
A(T t, Collection<? extends A<? extends T>> cOfAs) {
}
}
class B<R> extends A<Pair<R,R>> { // Pair is just a POJO class
B(Pair<R,R> pair, Collection<? extends B<? extends R>> cOfBs) {
super(pair, cOfBs);
// ERROR: The constructor A<Pair<R,R>>(Pair<R,R>, Collection<capture#1-of ? extends B<? extends R>>) is undefined
}
}
The type of the second parameter doesn't match. The B constructor takes Collection<? extends B<? extends R>>, but the superclass constructor takes a Collection<? extends A<? extends T>>.
You've defined T to be Pair<R, R> in your B class, so instead of R, use Pair<R, R>. Also the ? extends part must match, so change ? extends B<...> to ? extends A<...>. The signature of B's constructor now looks like this:
B(Pair<R,R> pair, Collection<? extends A<? extends Pair<R, R>>> cOfBs)
It must be ? extends A exactly, because ? extends B may not match ? extends A. The only way to get this to match is to introduce another type parameter in A representing the "self" type, and to use it in the second parameter of the constructor.
class A<T, S extends A<T, S>> {
A(T t, Collection<? extends S> cOfAs) {
}
}
Then in B, supply B<R> as "self".
class B<R> extends A<Pair<R,R>, B<R>> { // Pair is just a POJO class
B(Pair<R,R> pair, Collection<? extends B<R>> cOfBs) {
super(pair, cOfBs);
}
}
The type of second argument of constructor is wrong:
Error:(20, 25) java: incompatible types: java.util.Collection<capture#1 of ? extends Main.B<? extends R>> cannot be converted to java.util.Collection<? extends Main.A<? extends javafx.util.Pair<R,R>>>
To fix it change second argument to Collection<? extends B<R>> cOfBs
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
I'm creating a generic interface and its class implementation. It's a disjoint set. The generic type upper boundary for this class is generic itself:
public class MyDisjointSet<K extends Pair<T, T>> implements IMyDisjointSet<K> {
}
and
public interface IMyDisjointSet<T> {}
but I get compile error Cannot resolve symbol T.
When I add a second parameter to the list of generic types it works compiles:
public class MyDisjointSet<K extends Pair<T, T>, T> implements IMyDisjointSet<K>
Why should we put T here? why not before class name?
Please try
public class MyDisjointSet<K extends Pair<T, T>,T> implements IMyDisjointSet<K> {
I have a generic class with this definition:
public class AcoProblemSolver<C, E extends Environment, A extends AntColony<E, Ant<C, E>>> {
Where AntColony goes this way:
public abstract class AntColony<E extends Environment, A extends Ant<?, E>> {
And Ant goes like this:
public abstract class Ant<C, E extends Environment> {
I was hoping to extend AntColony in this fashion:
public class FlowShopProblemSolver extends
AcoProblemSolver<Integer, FlowShopEnvironment, FlowShopAntColony> {
But Eclipse is showing an error on the FlowShopAntColony parameter class:
Bound mismatch: The type FlowShopAntColony is not a valid substitute for the bounded parameter <A extends AntColony<E,Ant<C,E>>> of the type AcoProblemSolver<C,E,A>
Which confuses me, since FlowShopAntColony is defined this way:
public class FlowShopAntColony extends
AntColony<FlowShopEnvironment, AntForFlowShop> {
And AntForFlowShop goes like this:
public class AntForFlowShop extends Ant<Integer, FlowShopEnvironment> {
Why isn't FlowShopAntColony accepted as a valid parameter?
A extends AntColony<E, Ant<C, E>>
The third parameter of AcoProblemSolver has the restriction extends AntColony<E, Ant<C, E>>. The second parameter of AntColony must be exactly Ant<C, E> and you're trying to pass a subclass of Ant. Try:
A extends AntColony<E, ? extends Ant<C, E>>
You may want other similar ? extends clauses elsewhere.
I am in a strange situation here, namely eclipse tells me that Long is "not a valid substitute for the bounded parameter <T extends Comparable<? super T>>". Any suggestions on what may be the cause? I'm pasting relevant code below
abstract Pair:
public abstract class Pair<T extends Comparable<? super T>, R> implements Comparable<Pair<T, R>>{
private T tt;
private R rr;
public Pair(T t, R r){
tt = t;
rr = r;
}
#Override
public String toString(){
return tt+ ": " +rr.toString();
}
}
concrete Pair:
import utilities.Pair;
public class LogBookRecord<Long, String> extends Pair<Long, String>{
LogBookRecord(Comparable t, Object r) {
super(t, r);
// TODO Auto-generated constructor stub
}
}
I tried changing abstract class header to:
public abstract class Pair<T extends Comparable<T>, R> implements Comparable<Pair<T, R>>
which did not help, and also to:
public abstract class Pair<T, R> implements Comparable<Pair<T, R>>
but then, in concrete class I get a notification which suggests that I should change type parameters to <Comparable, Object>.
public class LogBookRecord<Long, String> extends Pair<Long, String>{
^ ^
| |
generic type variable declaration (new type names) |
generic type arguments
That code is equivalent to
public class LogBookRecord<T, R> extends Pair<T, R>{
You've simply shadowed the names Long and String with your own type variable names.
Since T has no bounds, it is not necessarily Comparable and the compiler cannot validate them as type arguments to Pair.
What you want is
public class LogBookRecord extends Pair<Long, String>{
A class that is not generic, that provides concrete types as type arguments to the Pair superclass declaration.
The Java Language Specification describes the class declaration syntax.
I am Studying Data Structures and I was asked to write a program that allows a store manager to manipulate an inventory , using 4 classes : ListInterface , ExpandableArrayList ( a class that implements the interface) , class item ( which is the type stored in the Arraylist) , and of course, a Test class.
some methods require the use of compareTo. that is , being Comparable , but I don't know what class exactly should be Comparable ?
and if I should write Implements or extends Comparable ?
these are the class headers I have right now :
public interface ListInterface<T extends Comparable <?super T >> {... }
public class ExpandableArrayList <T extends Comparable <? super T >>
implements ListInterface <T> { ...... }
public class Item<T extends Comparable<T>> {... }
but for some reason, I cannot create an Object in the Test class.
when I type:
ListInterface<Item> inventoryList= new ExpandableArrayList<Item>();
I get the following errors :
Test.java:9: error: type argument Item is not within bounds of type-variable T
ListInterface<Item> inventoryList= new ExpandableArrayList<Item> () ;
where T is a type-variable:
T extends Comparable<? super T> declared in interface ListInterface
Test.java:9: error: type argument Item is not within bounds of type-variable T
ListInterface<Item> inventoryList= new ExpandableArrayList<Item> () ;
where T is a type-variable:
T extends Comparable<? super T> declared in class ExpandableArrayList
How Can I solve this? what exactly should be changed? ..
thanks a lot in advance.
T which is your type Item needs to implement Comparable. This will allow the ExpandableArrayList class to run the compareTo method on elements of type Item using the comparison provided by that class. When you implement compareTo from Comparable you have to give a way for comparing different Items, this should be based on the attributes of the Item class ideally.
public class Item implements Comparable<Item> {... }
This is what the class def would look like.
You have to write implements for interfaces and extends for classes.
Inheritance tutorial
Interfaces tutorial
It should be like this -
public interface ListInterface<T extends Comparable<? super T>> {... }
public class ExpandableArrayList<T extends Comparable<? super T>> implements ListInterface <T extends Comparable<? super T>> { ...... }
public class Item implements Comparable<Item> {... }