Java two-way parameterized class - java

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

Related

The generic type upper bound to be generic itself

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> {

Extension of generic Java class does not recognize super constructor

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

Java generics: Bound mismatch

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.

when to use extends or implements Comparable (Java) ? + why I cannot create object

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> {... }

Java wildcards with super

I read that using a wildcard with super like this:
public class MyClass <T extends Comparable<? super T>> {
...
}
instead of:
public class MyClass <T extends Comparable<T>> {
...
}
could make the class 'more generic', but I do not understand why.
Can someone provide some concrete examples?
This way you can supply a class for T, which does not for itself implements Comparable, but inherits from a class implementing Comparable.
E.g.
class Baseclass implements Comparable<Baseclass> {
...
}
class Inherited extends Baseclass {
...
}
With a specification like
public class MyClass <T extends Comparable<? super T>> {
...
}
you can use MyClass<Inherited>, and MyClass<Baseclass>, but with
public class MyClass <T extends Comparable<T>> {
...
}
you can only use MyClass<Baseclass>

Categories

Resources