compareTo is asking me to cast, and I do not know why - java

Can someone explain why I am getting this error: The method compareTo(AVLNode) is undefined for the type AVLNode
Here is a shortened version of my Tree class:
public class AVLTree< E extends Comparable<E> >
{
private AVLNode<E> root ;
public AVLTree()
{
this.root = null;
}
public void insert ( AVLNode<E> item )
{
if( item.getLeft().compareTo(item.getItem() ) < 0) //ERROR IS HERE
{
}
}
}
Below is my a short version of my Node class
class AVLNode <E extends Comparable<E> >
{
private AVLNode<E> item;
private AVLNode<E> left;
public AVLNode ( AVLNode<E> item)
{
this.item = item;
this.left = null;
}
public AVLNode( AVLNode<E> item, AVLNode<E> lft )
{
this.item = item;
this.left = lft;
}
public AVLNode<E> getItem()
{
return this.item;
}
public AVLNode<E> getLeft()
{
return this.left;
}
}

Your Comparable base class assumes you're comparing to Es when you want to compare to AVLNode<E>s
So change it to inherit Comparable<AVLNode<E>> and see what happens.

Your AVLNode class should obviously look like this:
public class AVLNode<E extends Comparable<E>> {
private E item;
//...
public int compareTo(final E obj) {
return this.item.compareTo(obj);
}
Difference:
item should be of type E not AVLNode<E> because you want to store an E and not a AVLNode.
To state, that your AVLNodes are comparable, they could implement Comparable<T> themself by just delegating to E#compareTo() method:
public class AVLNode<E extends Comparable<E>> implements Comparable<AVLNode<E>> {
private E item;
//...
#Override
public int compareTo(final AVLNode<E> other) {
return this.item.compareTo(other.item);
}
}

getLeft() returns an AVLNode. You try and call getLeft().compareTo(...). This requires that AVLNode provides a matching method.
From this:
class AVLNode <E extends Comparable<E> >
{
private AVLNode<E> item;
...
It looks like your nodes can only hold other nodes. Presumably your items should actually be of the comparable type E. Then you can retrieve the item and call compareTo() on that.

That's because AVLNode doesn't have a method called compareTo() if you implement one then the issue should be solved.
You should also decide whether your want to compare E vs E or AVLNode vs AVLNode

Related

Build Logic Tree like the where clause in sql

I want to build a Logic Tree in Java which contains the conditions that could be used
for database insertions.
for example:
Node tree = input0.eq(3).and(input1.eq(1).or(input2.greaterThan(5)));
could be converted to:
WHERE input0=3 AND (input1 = 1 OR input2 > 5)
Since a Node could be a logical expression like and,or etc. as well as a Leaf with data, I thought a parent Node class and two child classes, would be ideal. But I have no idea how to handle nested expressions. I already read a few similiar questions here, but they weren't really specific enough.
public class Node {
public Long id;
public Node parent;
public List<Node> children;
}
public class LogicalNode extends Node {
LogicType logicType;
public LogicalNode () {
super();
}
getter and setter...
}
public class LeafNode extends Node {
Object input;
public LeafNode () {
super();
}
getter and setter...
}
public enum LogicType
{
AND("and"),
OR("or"),
NOT("not"),
EQ("="),
GREATER_THAN(">"),
LESSER_THAN("<");
private String name;
LogicType (String name) {
this.name= name;
}
public String getName() {
return name;
}
}
To get you started, try something similar to this:
public abstract class Node {
abstract void toSql();
Node eq(Node other) {
return new LogicalNode(LogicalType.EQ, this, other);
}
...
}
public class LeafNode extends Node {
LeafNode(int value) {
this.value = value;
}
String toSql() {
return this.value.toString();
}
}
public class LogicalNode extends Node {
LogicalNode(LogicalType type, Node left, Node right) {
this.logicalType = type;
this.left = left;
this.right = right;
}
String toSql() {
return String.format(
"(%s) %s (%s)",
this.left.toSql(),
this.logicalType.getName(),
this.right.toSql()
);
}
}
The key here is that the LogicalNode is constructed using two other Nodes, but it doesn't concern itself with whether or not they are LeafNodes or LogicalNodes. All LogicalNode knows is that it has two things that can be converted to a string using toSql.

Extending vs. implementing Comparable in java [duplicate]

This question already has answers here:
What is PECS (Producer Extends Consumer Super)?
(16 answers)
Closed 4 years ago.
I'm trying to implement binary search tree in java. It can take any object as the data of a node in the tree, as long as that object implements the Comparable interface. This is needed because while putting a new node in the tree, we need to decide, whether the new node is of lesser or greater value compared to its parent. My Node class looks something like the following.
package com.java.ds.bst;
public class Node<T extends Comparable<T>> implements Comparable<T> {
private T data;
private Node<T> left = null;
private Node<T> right = null;
public Node() {
this.data = null;
}
public Node(T data) {
this.data = data;
}
public T getValue() {
return this.data;
}
public Node<T> getLeft() {
return this.left;
}
public Node<T> getRight() {
return this.right;
}
public void setLeft(Node<T> left) {
this.left = left;
}
public void setRight(Node<T> right) {
this.right = right;
}
#Override
public int compareTo(T other) {
return this.data.compareTo(other);
}
}
What I don't understand is, in the class name declaration, why do I need T extends Comparable<T> instead of T implements Comparable<T>?
It is the syntax for generics, T extends Comparable<T> means it will accept anything that is Comparable<T>.
You are correct to use implements Comparable<T> when implementing the interface.

Java how to return a generic type that extends an interface

I have an interface named IDedObject and I am making a linkedlist class that uses generics that extend the IDedObject interface. In the linkedList class, I have a function that tries to find a given item based on it's data, and then returns that item. I am getting an error that says
Incompatible types. Required: AnyType. Found: IDedObject
This is what my code looks like:
Interface:
public interface IDedObject {
public int getID();
public void printID();
}
LinkedList:
public class singlyLinkedList<AnyType extends IDedObject> {
public Node<AnyType> endMarker;
public Node<AnyType> beginMarker;
AnyType findID(int ID){
Node curNode = beginMarker;
while(curNode.getNext() != endMarker){
if (curNode.getData().getID() == ID){
return curNode.getData();
}
}
return null;
}
}
class Node<AnyType extends IDedObject>{
public Node(AnyType d, Node<AnyType> n){
data = d;
next = n;
}
public Node getNext(){
return next;
}
public AnyType getData() {
return data;
}
public AnyType data;
private Node<AnyType> next;
private int theSize;
}
I appreciate any help with this. It's for a homework assignment, so i'm required to use a generic the extends IDedObject.
Thanks.
I fixed the problem by changing
Node curNode = beginMarker;
to
Node<AnyType> curNode = beginMarker;
in the findID function in the LinkedList class. Not sure how I missed that.

How to inherit parent's inner class in this code?

Below is the parent class DblyLinkList
package JavaCollections.list;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class DblyLinkList<T> implements Iterable<T>{
class DListNode<T> {
private T item;
private DListNode<T> prev;
private DListNode<T> next;
DListNode(T item, DListNode<T> p, DListNode<T> n) {
this.item = item;
this.prev = p;
this.next = n;
}
}
.....
}
Below is the derived class LockableList,
package JavaCollections.list;
import JavaCollections.list.DblyLinkList.DListNode;
public class LockableList<T> extends DblyLinkList<T> {
class LockableNode<T> extends DblyLinkList<T>.DListNode<T> {
/**
* lock the node during creation of a node.
*/
private boolean lock;
LockableNode(T item, DblyLinkList<T>.DListNode<T> p,
DblyLinkList<T>.DListNode<T> n) {
super(item, p, n); // this does not work
this.lock = false;
}
}
LockableNode<T> newNode(T item, DListNode<T> prev, DListNode<T> next) {
return new LockableNode(item, prev, next);
}
public LockableList() {
this.sentinel = this.newNode(null, this.sentinel, this.sentinel);
}
.....
}
If class LockableNode<T> extends DListNode<T> in the above code, error:The constructor DblyLinkList<T>.DListNode<T>(T, DblyLinkList<T>.DListNode<T>, DblyLinkList<T>.DListNode<T>) is undefined occurs at line super(item, p, n)
This error is resolved by saying: class LockableNode<T> extends DblyLinkList<T>.DListNode<T>
How do I understand this error? Why it got resolved?
You are redeclaring the type variable T in the inner class. That means that within the inner class, the T of the outer class is hidden and cannot be referred to anymore.
Since you have a non-static inner class, you can just remove the type variable T there:
class DListNode { ... }
because it inherits it from the containing class (and probably you mean that the variables are the same, anyway).

Java Generic type identification

This is my class structure.
public class Node<T> {
private T value;
public Node(T val) {
this.value = val;
}
public T evaluate() {
return value;
};
}
T can be Integer, Double, Date, Long or String.
Now, is there anyway I can get to know exactly what that type T is? Thanks.
You can invoke getClass() method on that generic variable and find out the class. Basically generics are erased at run-time, so an unbounded generic is nothing but java.lang.Object. So you can invoke all the method supported by Object class on that generic variable
At run-time, getClass() on generic object will return the actual class which was used to substitute the generic
For example
public class Node<T> {
private T value;
public Node(T val) {
Class<?> clazz = val.getClass();
checkType(clazz);
this.value = val;
}
public T evaluate() {
return value;
};
private void checkType(Class<?> c) {
if(c.getName().equals(Integer.class.getName())) {
//...
}
}
}
Much easier, use instanceof.
public class Node<T> {
private T value;
public Node(T val) {
checkType(val);
this.value = val;
}
public T evaluate() {
return value;
};
private void checkType(T val) {
if(val instanceof Integer) {
//...
}
}
}
Though there is already an accepted answer, I think it may be good to add one more answer:
As mentioned by #BaileyS, there is no way to get info of T in a place without an instance of T.
The solution greatly depends on why you want T, how you are using it. Normally, if we need the type of T for the logic (e.g. creating a new instance of T), it is usually done by providing the Class instance.
For example, you can make your Node class be:
public class Node<T> {
private T value;
private Class<T> valueType;
public Node(T val, Class<T> valueType) {
this.value = val;
this.valueType = valueType;
}
//.....
}
If you know that your node will store only Number you could restrict it.
public class Node<T extends Number> {
private final T value;
public Node(T val) {
this.value = val;
}
public T evaluate() {
return value;
};
public Class<? extends Number> type() {
return value.getClass();
}
}

Categories