I am trying to implement a generic binary tree. Here's the declaration of the node class
public abstract class Node<E extends Comparable<E>> {
}
A concrete Node:
public class BinaryTreeNode extends Node<BinaryTreeNode> implements
Comparable<BinaryTreeNode> {
#Override
public int compareTo(final BinaryTreeNode node) {
if (this == node) {
return 0;
}
return this.getValue().compareTo(node.getValue());
}
}
The abstract tree class
public abstract class BinaryTree<T extends Node<T>> {
/**
* TODO.
*/
public BinaryTree() {
}
/**
* TODO.
*
* #param node TODO
*/
public abstract void addNode(final T node);
/**
* TODO.
*
* #param node TODO
*/
public abstract void removeNode(final T node);
}
This is where I get the bound mismatch, because of the T parameter of Node. I have tried having it extend Comparable, but I jut cant get it to work. How do I need to declare this? I want to make the binary tree be able to work with all classes that extend Node.
Here's a concrete tree:
public class ConcreteBinaryTree extends BinaryTree {
private Node root;
#Override
public void addNode(Node node) {
// TODO Auto-generated method stub
}
#Override
public void removeNode(Node node) {
// TODO Auto-generated method stub
}
}
How do I need to add the type parameters here?
Your BinaryTree class needs to declare T as a Comparable too - you can use a type intersection for that:
public static abstract class BinaryTree<T extends Node<T> & Comparable<T>>
And your ConcreteBinaryTree class could look like this:
public class ConcreteBinaryTree extends BinaryTree<BinaryTreeNode> {
#Override
public void addNode(BinaryTreeNode node) { }
#Override
public void removeNode(BinaryTreeNode node) { }
}
Related
I have a class called Point, with a method neighbors() that returns an array of Points:
public class Point {
public Point[] neighbors() { /* implementation not shown */ }
}
I have a subclass of Point, called SpecialPoint that overrides neighbors() to return an array of SpecialPoints instead of Points. I think this is called covariant return types.
public class SpecialPoint extends Point {
public SpecialPoint[] neighbors() { /* implementation not shown */ }
}
In a separate class, I want to make use of Point and SpecialPoint with generics
public <P extends Point> P doStuff(P point) {
P[] neighbors = point.neighbors();
// more stuff here including return
}
This will not compile, because the compiler can only guarantee that P is some subclass of Point, but there is no guarantee that every subclass of Point will override neighbors() to return an array of itself as I happen to have done with SpecialPoint, so Java only knows that P#neighbors() returns Point[], not P[].
How do I guarantee that each subclass overrides neighbors() with a covariant return type so I can use it with generics?
You may use an interface:
public interface Point<P extends Point<P>> {
P[] neighbors();
}
public class SimplePoint implements Point<SimplePoint> {
#Override
public SimplePoint[] neighbors() { /* ... */ }
}
public class SpecialPoint implements Point<SpecialPoint> {
#Override
public SpecialPoint[] neighbors() { /* ... */ }
}
Then:
public <P extends Point<P>> P doStuff(P point) {
P[] neighbors = point.neighbors();
/* ... */
}
If you still need to factorize code between the implementations, then better use an abstract class:
public abstract class Point<P extends Point<P>> {
public abstract P[] neighbors();
public void commonMethod() { /* ... */ }
}
public class SimplePoint extends Point<SimplePoint> { /* ... */ }
public class SpecialPoint extends Point<SpecialPoint> { /* ... */ }
Possibly an interface Point solves your problem:
public class Test
{
public interface Point {
public Point[] neighbors();
}
public class SpecialPoint implements Point {
public SpecialPoint[] neighbors() { return null; }
}
public class SpecialPoint2 implements Point {
public SpecialPoint2[] neighbors() { return null; }
}
public Point doStuff(SpecialPoint point) {
Point[] neighbors = point.neighbors();
return neighbors[0];
}
public Point doStuff(SpecialPoint2 point) {
Point[] neighbors = point.neighbors();
return neighbors[0];
}
}
I have a class
private class BSTNode<E extends Comparable<E>> implements Comparable<E> {
BSTNode<E> left, right;
E data;
with constructor and compairTo method
but when I want instantiate the BSTNode class I face problem.
public class BST {
private BSTNode<E> root;
/* Constructor */
public BST() {
root = new BSTNode<E>();
}
how should I use BSTNode in my BST class ? Thanks
Something on these lines (not full fledge or concrete):
public class BST<E extends Comparable<E>>
{
private class BSTNode<E extends Comparable<E>> implements Comparable<E> {
BSTNode<E> left, right;
E data;
#Override
public int compareTo(E o) {
return 0;//implement method here
}
}
private BSTNode<E> root;
public BST() {
root = new BSTNode<E>();//while comparing you would need to case E to comparable and call compareTo method
}
public static void main(String[] args)
{
BST<String> messages = new BST<String>();
}
}
Your class header means that your BTSNode may only be instantiated with classes E which implement the Comparable interface.
As such, you should be able to use it as below:
public class BST {
private BSTNode<Integer> root;
/* Constructor */
public BST() {
root = new BSTNode<Integer>();
}
}
Integer may be replaced with any of the other implementing classes listed here or your even own custom implementation.
I'm trying to define void add(T thing) method by using the inherited push method of a stack but Eclipse says the return type is incompatible with Vector<T>.add(T) and wants me to change the return type of add(T) to boolean which doesn't make sense.
Below is my code
public class ListStack<T> extends Stack<T> implements SomeList<T>{
Stack<T> stack1=new Stack<T>();
public ListStack(){//constructor
super();
stack1=new Stack<T>();
}
//add method
public void add(T something){
this.push(something);}
}
Here's my SomeList interface
public interface SomeList<T>{
public void add(T something);
public void take(T idx);
.
.
.
}
Well since you're holding an instance of Stack<T> as member you don't need to inherit from the very same class.
Remove the inheritance and use your member instead:
public void add(T something){
stack1.push(something);
}
If you no longer subclass Stack<T> your compiler shouldn't complain about the different return types of add(T) anymore.
I think you should have a look into the adapter pattern.
Here's how I would do it:
Interface
interface MyList<T> {
public void addFront(T thing);
public void remove(int pos);
public void removeEnd();
public T get(int pos);
public int length();
public boolean isEmpty();
}
Implementation
class MyListImpl<T> implements MyList {
Stack<T> mStack;
public MyListImpl() {
mStack = new Stack<T>();
}
public void addFront(T thing) {
mStack.push(thing);
}
public void remove(int pos) {
//mStack...
}
public void removeEnd() {
//mStack...
}
public T get(int pos) {
// return mStack...
}
public int length() {
// return mStack...
}
public boolean isEmpty() {
// return mStack...
}
}
Your Stack Class must be having the method add() with a return type of boolean
Stack class extends Vector class, which contains boolean add(E e). I think Eclipse confuses between the add method in Vector, and the add method in your SomeList interface.
I am a generics newbie and I am not able to find out the best way to achieve this. Please feel free to point out if I am doing something obviously wrong.
interface Node<T> {
void addOne(Node<T> node);
}
class StringNode implements Node<String> {
List<StringNode> data = new ArrayList<>();
/**
* {#inheritDoc}
*/
#Override
public void addOne(Node<String> node) {
StringNode stringNode = (StringNode) node;
data.add(stringNode);
}
}
I was hoping to find a way to avoid the downcast from Node to StringNode in the implementation of addOne by having the function itself be of signature public void addOne(StringNode node). Any ideas as to how the definition of Node can be changed to achieve this for any implementation of the interface?
I tried searching through the questions already asked, but was not able to find a close match. Any pointers to questions where this has already been discussed would also be greatly appreciated.
Thanks in advance!
Why are you using String and StringNode separatly? Couldn't you just say
interface Node<T> {
void addOne(T node);
}
class StringNode implements Node<StringNode> {
List<StringNode> data = new ArrayList<StringNode>();
/**
* {#inheritDoc}
*/
#Override
public void addOne(StringNode node) {
StringNode stringNode = node;
data.add(stringNode);
}
}
This is how I would have done it:
interface Node<T extends Node<T>> {
void addOne(T node);
}
class StringNode implements Node<StringNode> {
List<StringNode> data = new ArrayList<StringNode>();
/**
* {#inheritDoc}
*/
#Override
public void addOne(StringNode node) {
data.add(node);
}
}
Similar to U-No-Poo's suggestion, but a little more strict (forces T to actually be a node)
You could introduce another generic parameter:
public interface Node<VALUE_TYPE, SELF> {
public void addOne(SELF u);
}
public class StringNode implements Node<String, StringNode> {
#Override
public void addOne(StringNode u) {
// TODO Auto-generated method stub
}
}
Use VALUE_TYPE whenever you need the actual value type (in this case String) and SELF whenever you want to pass a node of that type.
I'm writing a class for a binary tree, and in the tree interface this function is defined:
/** Returns an iterable collection of the the nodes. */
public Iterable<Position<E>> positions();
The problem is that the type of the node is MY class implementing the position interface in the task. Not the interface itself, Position. That is why I'm having trouble returning an iterable list of the nodes.
#Override
public Iterable<Position<E>> positions() {
ArrayList<Posisjon<E>> liste = new ArrayList<Posisjon<E>>();
liste = dumpings(liste,root);
System.out.println(liste.get(0));
return (Iterable<Position<E>>) liste.Iterator(); //PROBLEM HERE!
}
I use a recursive helper function to extract the elements and add them to an ArrayList and then just return the iterator for the list. "liste" here is of type my class "Posisjon" and the expected return for the function is the interface "Position". Why can't I just use return type "Posisjon" since it is implementing interface "Position"? Nor can I change the return type because the return type is specified in the tree interface which I must implement.
Here is the interface "Position" and my class "Posisjon" in case it helps you to understand the problem. (Node interface and Node class if you will).
public interface Position<E> {
/** Return the element stored at this position. */
E element();
}
public class Posisjon<E> implements Position<E> {
private E element;
private Posisjon<E> parenten;
private Posisjon<E> rightChildren;
private Posisjon<E> leftChildren;
#Override
public E element() {
return element;
}
public E setElement(E ting){
E tmpElement = element;
this.element = ting;
return tmpElement;
}
public Posisjon<E> leftChild(){
return leftChildren;
}
public Posisjon<E> rightChild(){
return rightChildren;
}
public Posisjon<E> parent(){
return parenten;
}
public Posisjon(E element){
this.element = element;
}
public void setLeftChild(Posisjon<E> ting){
this.leftChildren = ting;
}
public void setRightChild(Posisjon<E> ting){
this.rightChildren = ting;
}
}
You want
public Iterable<? extends Position<E>> positions();
There are very good reasons why Iterable<A> does not extend Iterable<B> when A extends B. The solution in Java is to use wildcards as above.
You should define your method as:
public Iterable<? extends Position<E>> positions();