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.
Related
So, I have a generic class BinaryTree that I used as source code that has a type parameter called Node (which I normally see as T). The class looks something like this:
public class BinaryTree<Node extends BinaryTree.BTNode<Node>> {
public static class BTNode<Node extends BTNode<Node>> {
public Node left;
public Node right;
public Node parent;
}
public BinaryTree(Node sampleNode) {
this.sampleNode = sampleNode;
}
//Some methods
}
Normally, (with my other generic classes), assuming it passes the type into its constructor, I invoked it by doing this:
BinaryTree<Integer> myTree=new BinaryTree<Integer>(Integer.class);
But of course this doesn't work as it wants type Node which extends BTNode. How would I reference a Node extending BTNode so that I can create an instance of BinaryTree?
If you change the type parameter of the BTNode class a bit, it becomes possible:
class BinaryTree<Node extends BinaryTree.BTNode>
{
static class BTNode<T> {
T value;
public BTNode<T> left;
public BTNode<T> right;
public BTNode<T> parent;
BTNode(T value) {
this.value = value;
}
}
private Node root;
public BinaryTree(Node node) {
root = node;
}
}
And usage:
class CustomNode extends BinaryTree.BTNode<Integer> {
CustomNode(Integer value) {
super(value);
}
}
BinaryTree<CustomNode> bt = new BinaryTree<>(new CustomNode(10));
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) { }
}
I have a Node class:
public class Node<T extends MySuperClass> {
private T data;
private Node<? extends MySuperClass> parent;
private List<Node<? extends MySuperClass>> children;
public Node(T data, Node<? extends MySuperClass> parent, List<Node<? extends MySuperClass>> children) {
this.data = data;
this.parent = parent;
this.children = children;
}
public T getData() {
return data;
}
public Node<? extends MySuperClass> getParent() {
return parent;
}
public List<Node<? extends MySuperClass>> getChildren() {
return children;
}
public void setData(T data) {
this.data = data;
}
public void setParent(Node<? extends MySuperClass> parent) {
this.parent = parent;
}
public void setChildren(List<Node<? extends MySuperClass>> children) {
this.children = children;
}
}
I need to create a map of Generic Node defined above. I have to write something like this
List<Map<Long, Node<? extends MySuperClass>>> tree = new ArrayList<Map<Long, Node< extends MySuperClass>>>();
When I try to add an instance of map to the list
public MyClass extends MySuperClass{
}
Map<Long, Node<MyClass>> myMap = new HashMap<Long,Node<MyClass>>();
tree.add(myMap);
The Compiler gives me the following message:
The method add(Map<Long,Node<? extends MySuperClass>>) in the type List<Map<Long,Node<? extends MySuperClass>>> is not applicable for the arguments (Map<Long,Node<MyClass>>)
Syntactically it is correct. I Can't understand why it doesn't work.
Your Map should be defined the same type as your List.
This is because the List expects a type of Map<Long, Node<? extends MySuperClass>>. The type Node<? extends MySuperClass> and Node<MyClass> are not the same.
From http://docs.oracle.com/javase/tutorial/java/generics/inheritance.html
Note: Given two concrete types A and B (for example, Number and
Integer), MyClass<A> has no relationship to MyClass<B>, regardless of
whether or not A and B are related. The common parent of MyClass<A>
and MyClass<B> is Object.
Note : I add to add a default constructor to your Node class to get the next four lines to compile since I didnt want to type in the params for the other constructor.
List<Map<Long, Node<? extends MySuperClass>>> tree = new ArrayList<Map<Long, Node<? extends MySuperClass>>>();
Map<Long, Node<? extends MySuperClass>> myMap = new HashMap<Long, Node<? extends MySuperClass>>();
myMap.put(1L, new Node<MyClass>());
tree.add(myMap);
So I have an AbstractSyntaxTreeNode.java class (here is part of it)
public abstract class ASTreeNode implements Iterable<ASTreeNode>{
protected List<ASTreeNode> children;
protected ASTreeNode(){
children = new LinkedList<ASTreeNode>();
}
protected ASTreeNode(ASTreeNode... children){
this();
for(ASTreeNode c: children)
{
this.addChild(c);
}
And then I have another class Operation that extends ASTreeNode
public class Operation extends ASTreeNode
{
char s;
private Operation(Term t)
{
//QUESTION REGARDING THIS PART
super(t, t.getChild(0), t.getChild(1));
}
}
How do I throw in all of object t's (which also extends ASTreeNode) children into the super ctor arguments? Without hardcoding it like that? I tried super(t, t.children) but the constructor does not take a List in the argument, only ASTreeNodes
are taken.
Oh and this is class term
public class Term extends ASTreeNode
{
char symbol;
private Term(Factor f)
{
super(f, f.getChild(0));
}
}
And theres a bunch more classes that send up their children into another node
Add a constructor in ASTreeNode that accept's a List as it's argument.
public abstract class ASTreeNode ... {
public ASTreeNode(List<? extends ASTreeNode> children) {
this.children = children;
}
}
public class Operation extends ASTreeNode {
char s;
private Operation(Term t) {
super(t.getChildren());
this.addChild(t);
}
}
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();