Proper way of using generics for composition of elements in java - java

Tree contains elements of TreeNode with data elements of type T.
I define as below
class TreeNode<T>
{
T data;
}
The following dosen't make sense.
class Tree<TreeNode<T>>
{
TreeNode<T> node;
}
then case 1
class Tree
{
TreeNode<T> node;
}
but above gives error at T in line 3.
then case 2
class Tree<N extends TreeNode<T>>
{
TreeNode<T> node;
}
compiler complains at T in line line 1 - T cannot be resolved.
but below case 3 compiler is happy
class Tree<T extends TreeNode<T>>
{
TreeNode<T> node;
}
but the above dosen't make sense. it will be true as in the case like T extends Comparable, but here it says that Tree contains elements of type subtype TreeNode containing data of type T, which inturn is of type T, which says that TreeNode also contain elements of type TreeNode which is not my intention.
What is the right way of defining that Tree contains elements of type TreeNode of data elements T ?
and Tree contains elements of subtype TreeNode ?
Is there any way to tell to the compiler that T is declared in TreeNode class ?
Also how to paramerize TreeNode and Tree saying that TreeNode contains elements of type T and also had pointers for TreeNode left child and right child ?

Related

Doubly Linked List with generic node type

I need a doubly linked list that can work on different node implementations. Note that I do not want nodes that contain generic data, like DoublyLinkedNode<T>, but something like DoublyLinkedList<N extends DoublyLinkedNode<T>>.
To be precise, I use the list in the general case with standard nodes, but in other parts of my program I need nodes with additional fields. So I implemented the general node as
public class DoublyLinkedNode<T> {
DoublyLinkedNode<T> before, after;
T value;
}
and the special type as
public class DoublyLinkedSpecialNode<T, S> extends DoublyLinkedNode<T> {
S specialValue;
}
Now in my DoublyLinkedList implementation I want to be able to handle both cases at one, because all the code basically fiddles around with the pointers that are obviously common to both implementations.
This gives a few requirements:
1) When I use the special node, I want to be able to return it as the DoublyLinkedSpecialNode type to be able to access the additional fields.
2) The list must use a DoublyLinkedNode type to access the pointers of the nodes.
3) The list is assigning the pointed-to nodes to other nodes, e.g. head = node.after;, so the type of the pointers in the special node must be the same as the type in the list.
Extending the list makes no sense because then I could not change the return type of the methods. Therefore I tried two ideas without success:
The already mentioned solution: Generic node type that extends from DLN
The list would look like this:
public class DoublyLinkedList<T, N extends DoublyLinkedNode<T>> {
N head, tail;
N tail() {
return tail; // OK
}
void remove(N node) {
if (head == node) {
head = node.after; // Type error
}
...
This solution conflicts with requirement 3), because in the list the type is an N that extends from DLN, but in the node implementation N the pointer is of the type of the base class/interface DLN (the pointer type could theoretically be more general than N).
Base DLN instead of generics
In this case the list works on the base class node and accepts the subclasses because of polymorphism:
public class DoublyLinkedList<T> {
DoublyLinkedNode<T> head, tail;
DoublyLinkedNode<T> tail() {
return tail;
}
void remove(DoublyLinkedNode<T> node) {
if (head == node) {
head = node.after; // OK
}
...
But tail() can only return nodes as the general type, conflicting with 1). I would prefer not to use casting, because I assume it's bad practice (?) but also because the implementation is performance critical. There surely is a better way?
I found another solution that is okay-ish, not very performant but more elegant than the last solution.
The idea ist to use only one type of nodes, and wrap the varying content in a generic container. The DLN code looks like this:
public class DoublyLinkedNode<C> {
DoublyLinkedNode<C> before, after;
C content;
public static class ValueContent<T> {
T value;
}
public static class ValueSpecialContent<T, S> extends ValueContent<T> {
S specialValue;
}
}
The list implementation then looks something like this:
public class DoublyLinkedList<C> {
DoublyLinkedNode<C> head, tail;
public DoublyLinkedNode<C> head() {
return head;
}
void remove(DoublyLinkedNode<C> node) {
if (head == node) {
head = node.after;
...
And I can access the special field from the calling class like this:
DoublyLinkedList<SpecialContent<SpecialType>> list;
SpecialType s = list.head().content.specialValue;
There is some overhead because each node has to instantiate that container class, but I think it's still better than casting. I have to check the performance impact.

Implementing a generic node [duplicate]

This question already has answers here:
What does the 'new' keyword actually do in Java, and should I avoid creating new objects?
(6 answers)
Closed 5 years ago.
I keep receiving an error when I'm trying to implement a node with generic data types. the node must be able to take an int input as well as a fraction input. what am i doing wrong? The compiler says that "method Node(A) is undefined for class BinarySearchtree
//creates a generic binary search tree class
public class BinarySearchTree<A> {
//the root of the node, which is the middle value
Node root;
//this constructor will add a node
public void addNode(A userNumber){
Node<A> newNode = Node<A>(A userNumber);
}//end addNode
public class Node<T>{
//this generic variable will become the user input either int or fraction
private T number;
//nodes that will become the left of right child of a parent node
Node<T> leftChild;
Node<T> rightChild;
//a node constructor that will take a generic input
Node(T number){
this.number = number;
}//end node constructor
}//end the Node class
}//end binary search tree
Instead of
Node<A> newNode = Node<A>(A userNumber);
use
Node<A> newNode = new Node<A>(A userNumber);
You don't have any method Node which the compiler gladly tells you about.

Can a variable be declared in java using class name only?

Can a variable be declared in java using the name of a subclass? I found this piece of code about linked lists very confusing. See, how the head of the list has been declared. Can someone please explain?
class LinkedList
{
Node head; // head of list
/* Linked list Node*/
class Node
{
int data;
Node next;
// Constructor to create a new node
// Next is by default initialized
// as null
Node(int d)
{
data = d;
}
}
}
Yes, an object can indeed contain a reference to another object of the same type as an instance member.
For example, this is the standard class definition of a Linked List Node:
class Node {
int value;
Node next;
... // instance methods follow
}
You have the current node which must point to a reference of the next node in the linked list.

JAVA Why do I get a type error when assigning these variables (T extends Comparable<T>)

So, let's say we have these two classes.
public class Main<T extends Comparable<T>> {
public List<T> toList(T t){
Node n = new Node();
n.value = t; //This assignment1 gives no issues.
List<T> list = new List<T>();
list.add(n.value); //This assignment2 gives a type error.
return list;
}
}
class Node <T extends Comparable<T>> {
T value = null;
}
So, why does assignment1 go through without a type error, while assignment2 gives me the following error:
add (T) in List cannot be applied to (java.lang.Comparable)
It disappears when I do:
list.add((T)n.value);
But I would like to understand the reason first to figure out if above solution is the correct one.
EDIT: For now, I should specify that the code that uses these classes are Integer objects. So, I as the developer can assume that the T types are the same. But I am not sure if the code has some underlying routine that can change the values during casting.
Node n = new Node();
should be
Node<T> n = new Node<T>();
If you ever refer to Node without <something> after it, you are telling the compiler to ignore all type checking on Node. This will give you warnings, as it should.

Getting a compilation error when implement interface comparable

I am trying to using the compareTo method for a generic Node type E.
I have already bound E to Comparable
public class LinkedList<E extends Comparable<E>> {
// ----------------------------------------------------------
// Implementing the doubly linked nodes (static nested class)
// ----------------------------------------------------------
private static class Node<E extends Comparable<E>> {
This method isSorted is implemented within the LinkedList class, the Node class is within the Linkedlist class.
I keep getting a compilation error "The method compareTo(LinkedList.Node) is undefined for the type LinkedList.Node"
I believe that only pops up when E is not extending Comparable, in my case it is.
Any help?
public boolean isSorted( ){
if(!isEmpty()){
Node<E> temp = head;
boolean local = true;
int x=0;
while (temp.next != null){
x=temp.compareTo(temp.next);
if(x<0){
temp = temp.next;}
else {return local;}
}
return local;}
else{ throw new IllegalArgumentException();}
}
I checked this thread already, How to compare generic nodes in a linked list using Comparable?
It didn't help.
Thank you in advance
Mjall2
You're trying to compare the nodes, when it's only the values inside the nodes that are Comparable. Instead of temp.compareTo(temp.next), you probably want something like temp.value.compareTo(temp.next.value).

Categories