how do I correctly write following class declaration in Java?
public class BinarySearchTree<T extends BinarySearchNode<E implements Comparable<E>>> implements Iterable<E>
Basically, I am trying to create a BinarySearchTree of any class T that inherits BinarySearchNode of a Comparable datatype E (And my BinarySearchTree should also be Iterable).
How can I properly declare that class in Java?
Thanks!
public class BinarySearchTree<T extends BinarySearchNode<E>, E extends Comparable<E>> implements Iterable<E>
The type parameter E needs to be defined separately from the node type, even if it ends up looking redundant: BinarySearchTree<BinarySearchNode<String>, String>. Java won't let you directly access a generic parameter of a generic type.
Also, note that generic parameters always use "extends" even with interfaces.
With Generics in Java, you will only use extends. So, essentially your method decoration would become:
public class BinarySearchTree<T extends BinarySearchNode<E extends Comparable<E>>> extends Iterable<T>
Even for those classes that implement an interface, generics will use extends. The only other syntax for generics is super if you are looking at the inheritance from the opposite direction
Related
I am trying to understand this recursive interface definition in apache thrift source code
public interface TBase<T extends TBase<?, ?>, F extends TFieldIdEnum> extends Comparable<T>, Serializable {
From my understanding TBase is a interface containing type parameter T and F.
T has the constraint that it also have to be extending TBase that has type parameter containing any type.
What I am confused about is what is the terminating TBase
Say I have
public class TBaseImpl<A, B> implements TBase<A, B>
A has to be a TBase
so there must be another class implement A
public class TBaseImplA<C, D> implements TBase<C, D>
but C have to be a TBase
so there must be another class implement C
This goes on forever.
So my question is
What is terminating condition for TBase
What is the benefit of this recursive definition?
Can someone point me a direction?
Thanks
so there must be another class implement A
That is not necessarily true. With this type of recursive bounds, there are 2 possible ways to satisfy the constraint when creating a subtype.
Declare your own type parameter with the same or more restrictive bounds. This places the burden of choosing the type parameter on the user of this class.
public class TBaseImpl<A extends TBase<A, B>, B extends TFieldIdEnum> implements TBase<A, B>
or more likely
public class TBaseImpl<A extends TBaseImpl<A, B>, B extends TFieldIdEnum> implements TBase<A, B>
Pass the same class as what you're defining to satisfy the original bound.
public class TBaseImpl<B extends TFieldIdEnum> implements TBase<TBaseImpl, B>
A benefit of this pattern is being able to restrict the parameter of a method that is meant to take in another instance of the same class, e.g.:
public void example(T other)
This is (in Java) the Curiously Repeating Template Pattern.
Normally an implementing/overriding method must match the parameter types and order of parameters exactly. But this pattern allows you to narrow the type by narrowing the type parameter. E.g. such a method in TBaseImpl in this case would only take a TBaseImpl and not the broader T or TBase. In such a class there is a relationship between the class and itself.
Another benefit is method chaining, in which a method returns this to allow
obj.method1().method2().method3()
In this way, chaining methods can be declared to return T, so that e.g. a TBase<TBaseImpl> variable can call these methods, each returning a TBaseImpl on which another method can be called.
T method1(); // in TBase
#Override
TBaseImpl method1(); // in TBaseImpl
Incidentally, if you're trying to declare a type variable that is a subtype of an enum, that's not necessary because an enum is final and cannot be extended. It would be simpler to remove F in the interface and have implementing classes use the enum directly.
I don't understand why Company compiled. I thought it checked for extends but not for implements?
public interface Employee
public class HourlyEmployee implements Employee
public class Company<T extends Employee>
Company<HourlyEmployee> company = new Company<>();
The extends keyword in Generics has a slightly different semantics than the general extends keyword.
When using extends in the context of Generics, for example T extends Something, this means that T should be a type that either implements the interface Something (in cases when Something is interface), or is a subclass of Something (in case Something is a class).
Probably the reason for this is that if the implements keyword was supported in Generics, this would have made type-parameter declaration too verbose.
For example, you'd have:
<T extends SomeClass implements Serializable & Observable>
Instead, the valid syntax for this would be:
<T extends SomeClass & Serializable & Observable>
And you don't need to have the implements keyword, actually. When defining the bounds of a type T, you just need to point out which types does your type T derive from, without caring if those are interfaces or classes.
The type definition is not a class definition. You can consider type definition as joining few data sets, where the resulting set is your type T.
The notation T extends Employee in the declaration of a type parameter refers to either extending a class or implementing an interface.
public class Company<T implements Employee> is not a valid syntax.
Therefore public class Company<T extends Employee> means that the generic type parameter T of your Company class must implement the Employee interface.
I encountered the following piece of a definition for a generic class:
public class binarysearchnode<T extends Comparable<T>> implements Comparable<binarysearchnode<T>>{
.............
}
Please help explaining why a class would specify itself as a Type parameter to comparable while implementing the comparable interface?
How would it be different from the following:
public class binarysearchnode<T extends Comparable<T>> implements Comparable<? super (or extends)T>{
.............
}
This makes it possible to compare binarysearchnodes to each other. If it implemented Comparable<T>, that would instead mean that the node could be compared to the value of the node, which would be odd.
Inside the class you will probably find something like this:
T value;
public int compareTo(binarysearchnode<T> other) {
return value.compareTo(other.value);
}
In order to be able to implement compareTo() like this, the value class (T) needs to be comparable to other objects of its class - hence the declaration of <T extends Comparable<T>> in the class definition.
It is because what the class author wants is to be able to write:
b1.compareTo(b2)
where b1 and b2 are binarysearchnode instances. The developer also adds a constraint to T so that T extends Comparable<T>. Probably so that the implementation of Comparable for binarysearchnode can just rely on T instances being Comparable themselves.
More generally, while it is possible for a class C1 to implement Comparable<C2>, ultimately, it makes no sense to do so: this does not mean that an instance of C2 could be comparable to an instance of C1. And due to type erasure, it would not be possible, for instance, for class C1 to implement both Comparable<C1> and Comparable<C2>.
Also, if binarysearchnode<T> were to implement Comparable<T> directly, you would have at least two problems:
you would not be able to compare one binarysearchnode<T> to another;
given a binarysearchnote<T> instance b and a T instance t, you would be able to write b.compareTo(t) but not t.compareTo(b) (since T does not, and cannot, implement Comparable<binarysearchnode<T>>), and that breaks the Comparable contract.
Let's say you have a superclass A and a subclass B. Imagine the superclass implements Comparable<A>, then B will also implement Comparable<A> through inheritance.
Your binarysearchnode class declared as such :
public class binarysearchnode<T extends Comparable<T>>
will not be able to take B as a type parameter for T (B does not implement Comparable<B>)
But when defined as such :
public class binarysearchnode<T extends Comparable<? super T>>
it will be able to take B as a type parameter for T, since B implements Comparable<A> which fulfills Comparable<? super T>.
How to use Comparable interface with generic static method?
Suppose lets say I have:
**public static <T extends Comparable<T>>int larger(T[] array,T element)**
Why should I extend an Interface with T here instead of using implements?
Please Help me out.Thanks.
According to Java generics, you should use extends even to interfaces, there's no such thing as impelements in bounded types.
I have couple of thoughts regarding the following:
public interface MaxStack<T extends Comparable <T>>
1-Why does the class that implements MaxStack should be written like this:
public class MaxStackclass<T extends Comparable <T>> implements MaxStack<T>
and not public class MaxStackclass<T extends Comparable <T>> implements MaxStack<T extends Comparable <T>>?
2- why do the private variables of this class, when I use generics, should be written only with <T> and not with <T extnds Comparable<T>>? For example, private List<T> stack= new ArrayList<T>();
3-What is the difference between <T extends Comparable<T>> and <T extends Comparable>- if I need to compare bewteen elements in my class, both will be O.K, no?
Edit: I think that thee problem with 3 is that maybe it allows to insert of a list that was defined in the second way to have different elements which all extends from comparable and then when I want to compare them, it won't be possible, since we can't compare String to Integer, both extend from Comparable.
In the declaration maxStackclass<T extends Comparable <T>> you have already expressed the bounds on T. So you do not need it again.
Reason same as above. No need to specify bounds on the same type parameter again.
<T extends Comparable<T>> means that T must implement the Comparable interface that can compare two T instances. While <T extends Comparable> means T implements Comparable such that it can compare two Objects in general. The former is more specific.
if I need to compare bewteen elements in my class, both will be O.K,
no?
Well, technically you can achieve the same result using both. But for the declaration <T extends Comparable> it will involve unnecessary casts which you can avoid using the type safe <T extends Comparable<T>>
1) the class has a type parameter T with a bound (extends Comparable <T>), this parameter is passed to the interface (which need the same bound here). When passing a type parameter, you must not repeat its bound - why you should do so?
2) like 1), the type parameter has its bound declared, no repeat neccessary.
To clarify:
The first type parameter occurence (here behind the interface or class name) is its declaration. Any following occurence is a usage. You even never would write a variables type declaration each time you use it, right?
"3-What is the difference between <T extends Comparable<T>> and <T extends Comparable>- if I need to compare bewteen elements in my class, both will be O.K, no?"
No, both will not be okay. Suppose I have a class Foo which implements Comparable<Bar> but classes Foo and Bar have no relation to each other. Then Foo cannot compare to other objects of type Foo. <T extends Comparable<T>> will catch this as a problem. <T extends Comparable> will not.