Generic in Java throwing errors when methods are defined - java

I am learning Generics in Java. For that, I tried out a simple LinkedList like that.
class Node {
private int age;
private String name;
private Node next;
public Node(int age, String name) {
this.age = age;
this.name = name;
this.next = null;
}
public int getAge() {
return this.age;
}
public String getName() {
return this.name;
}
public Node getNext() {
return this.next;
}
public void setNext(Node next) {
this.next = next;
}
}
class LinkedList<T> {
private T head;
private T current;
public LinkedList() {
head = null;
current = null;
}
public void append(T x) {
if (head == null) {
head = x;
current = x;
}
else {
current.setNext(x);
current = x;
}
}
public T getAt(int index) {
T ptr = head;
for(int i = 0; i < index; i++) {
ptr = ptr.getNext();
}
return ptr;
}
}
class Main {
public static void main(String[] args) {
LinkedList<Node> list = new LinkedList<Node>();
list.append(new Node(39, "John"));
list.append(new Node(43, "Josh"));
Node x = list.getAt(1);
System.out.println(String.format("%d, %s", x.getAge(), x.getName()));
}
}
But I get this error, while all the methods do exist in the Node class. What mistake am I doing?
LinkedList.java:16: error: cannot find symbol
current.setNext(x);
^
symbol: method setNext(T)
location: variable current of type T
where T is a type-variable:
T extends Object declared in class LinkedList
LinkedList.java:24: error: cannot find symbol
ptr = ptr.getNext();
^
symbol: method getNext()
location: variable ptr of type T
where T is a type-variable:
T extends Object declared in class LinkedList
2 errors

If current is of type T, you can't call methods of the Node class (such as setNext()) on current, since T can be substituted by any class when you instantiate your LinkedList.
Your Node class shouldn't be the generic type argument of LinkedList. A LinkedList should always be made of Nodes. The type of the data stored in each Node should be a generic type.
class Node<T> {
private T data;
private Node next;
public Node(T data) {
this.data = data;
this.next = null;
}
}
And the LinkedList should contain Node<T> nodes:
class LinkedList<T> {
private Node<T> head;
private Node<T> current;
}

Compiler is unable to understand T type. You have used t.setNext() , however it is isn't present in T definition unless actually used. I might sound a bit confusing here but try this:
Create an Interface Contract having setNext and getNext method.
Implement Node extending above interface. Node implements Contract.
In Linked List change generics to T extends Contract

There is no hasNext for any given generic T, so the code doesn't compile
You'd have to make sure that the LinkedList only holds Node classes or its subtypes
class LinkedList<T extends Node>
But note: That T is not the same as the generic stored within the nodes, so this seems better
class LinkedList<T> {
Node<T> head;

private T current; is a generic type and you are calling setNext and getNext on it. How come T know that it always have these methods? That's the reason it's not working.
Hence, you need to ensure that your generic type T knows that it has setNext and getNext methods.
Hence the fix is:
T extends NodeAbstract in class definition where NodeAbstract is the interface declaring signature of these methods. now this ensures that anything T gets is always going to have these two methods.

You must make Node<T> and LinkedList<Node>.
public void append(T x) { // Here x is of Type T
if (head == null) {
head = x;
current = x; //Assigning x to current, current is also of Type T
}
else {
current.setNext(x); // T.setNext is not defined! Because T can be a String/Integer/whatever. They do not have setNext method
current = x;
}
}

Related

name clash when trying to overwrite method

this is my first post here, but I need help trying to figure out why my child class will not let me override the parent method. I was tasked to create a generic Binary Search Tree with some functionality. The next task was to create a generic AVL Tree and I decided to extend it from my custom Binary Search Tree to reuse code and simply add the rotation required to make it functional. However when trying to overwrite the method, I keep getting a name clash error. And if I get rid of my Comparable interface extension in my AVLTree class and make my insert method generic, I get an argument mismatch error saying T cannot be converted to Comparable. This is where I am stuck at, if anyone can offer any type of input it would be much appreciated.
public class BinaryTree <T extends Comparable<T>>{
Node Root;
public BinaryTree(){
this.Root = null;
}
public boolean isEmpty(){
return this.Root == null;
}
public void insert(T data){
this.insert(data, this.Root);
}
protected void insert(T data, Node<T> n){
if(this.Root == null){
this.Root = new Node(data);
}
if(data.equals(n.getData())){
n.occurances++;
}
else if(data.compareTo(n.data) < 0){
if(n.left != null)
insert(data, n.left);
else
n.left = new Node(data);
}
else if(data.compareTo(n.data) > 0){
if(n.right != null)
insert(data, n.right);
else
n.right = new Node(data);
}
}
First attempt:
public class AVLTree <T extends Comparable<T>> extends BinaryTree{
private static final int ALLOWED_IMBALANCE = 1;
public void insert(T data){
this.insert(data, this.Root);
}
Second attempt:
public class AVLTree extends BinaryTree{
private static final int ALLOWED_IMBALANCE = 1;
public <T>void insert(T data){
this.insert(data, this.Root);
}
error for overwriting insert method
Try passing the type parameter of BinaryTree:
// vvv
public class AVLTree <T extends Comparable<T>> extends BinaryTree<T> {
private static final int ALLOWED_IMBALANCE = 1;
#Override
public void insert(T data){
this.insert(data, this.Root);
}
}

How do I implement abstraction and generics in java?

I currently have a project that requires the use of abstraction and generics, but I don't even know where I should start for this. The abstract class is as follows.
public abstract class Links<AType> {
abstract AType getElem(); //returns the head of the list
abstract Links<AType> getNext(); //return the next link
}
This is the class that extends the abstract class
public class Cons<AType> extends Links<AType> {
AType elem;
Links<AType> next;
Cons(AType elem, Links<AType> next) {
this.elem = elem;
this.next = next;
}
#Override
AType getElem() {
return elem;
}
#Override
Links<AType> getNext() {
return next;
}
}
Here's another class that extends the abstract class
public class Nil<AType> extends Links<AType> {
Nil(){}
#Override
AType getElem() {
return null;
}
#Override
Links<AType> getNext() {
return null;
}
}
And here is the class that is supposed to implement everything
public class LList<AType> {
Links<AType> list;
LList() {
list = new Cons<>();
}
Links<AType> getList() {
return list;
}
AType get(int n, AType a) {
Cons<AType> aTypeCons = new Cons<>(a, list);
return null;
}
void add(AType elem) {
//add to head of list
}
void remove(int i) {
//remove ith element
//do nothing if i is invalid
}
void print() {
//prints the list
}
}
I just need some help figuring out where to actually start in making the LList class. I can't figure out the constructor because Links is abstract, so I can't make that an object, and I can't make a new Cons<> because there are no elements that are passed into the constructor. However, the constructor is supposed to instantiate a new list. I also can't figure out how I'm supposed to be able to access an individual element of that list. If I can just have a bit of understanding of what needs to happen in the constructor, I should be able to figure out how to implement the rest of the methods.
Your LList is a singly-linked list, where each element has a value and a link to the list that follows. The final element of the list will always be a Nil object, which represents an empty list. When you first initialize an empty list, you can just assign list = new Nil<>();. When you add an element to the list, you can reassign it as list = new Cons<>(elem, list);.
To access an an element in the list by index, just use a while loop that calls getNext() until it's either reached the desired index or found the end of the list.
AType get(int n) {
Links<AType> current = list;
while (n > 0 && current instanceof Cons) {
current = current.getNext();
n--;
}
return current.getElem();
}

comparable implementation in Java

I am new to Java and trying to implement MyLinkedList which extends the GeneralList interface, I want to use the comparable interface for my Node to keep my list sorted,
When I try to create a head node it is giving me errors
Please find the error message below the following code
//List interface
public interface GeneralList<T>
{
public boolean addNode(T elem);
public boolean deleteNode(T elem);
public T containsNode(T elem);
public void printSll();
}
//ListImplementation
public class SLL2<T> implements GeneralList<T>
{
private static class Node<T extends Comparable<T>>
{
public T data;
public Node<T> next;
public Node()
{
data = null;
next = null;
}
}
public SLL2()
{
head = null;
}
/* 1. Error while creating a head referance*/
private Node<T> head;
#Override
public boolean addNode(T elem)
{
Node<T> tmp = new Node<T>();
tmp.data = elem;
if(head == null)
{
head = temp;
return true;
}
else
{
for(Node<T> cur = head; cur.next != null ; cur= cur.next)
{
/* iterate and add the node */
if(temp.elem.comparTo(cur.elem))
{
}
}
}
}
1. I am not able to create the head node with the declaration private Node<T> head;
It is giving error "Bound mismatch: The type T is not a valid substitute for the bounded parameter <T extends Comparable<T>> of the type SLL2<T>.Node<T>"
Please help me to resolve this error...
Your class SLL2<T> should also have a constraint about comparability of T. Like that:
public class SLL2<T extends Comparable<T>> implements GeneralList<T> {
// ...

Generic Iterator implementation in java

I have the following design:
I have an Abstract class Instance,
I have a class Library that extends Instance and
I have a class File that also extends Instance
I've created my own linked list implementation and it's defined as follows:
public class List<T extends Instance> implements Iterable {
//some other code here
public Iterator iterator(){
return new ListIterator(this);
}
now I've created a class
public class ListIterator<T extends Instance> implements Iterator<T> {
private List thisList;
private Node current;
public ListIterator(List l){
thisList=l;
current=thisList.head.next;
}
#Override
public boolean hasNext() {
if(current==null)
return false;
return false;
}
#Override
public T next() {
Node temp=current;
current=current.next;
return temp.data;
}
}
Where Node is
public class Node<T extends Instance> {
public Node<T> next;
public Node<T> prev;
public T data;
public Node(T data,Node prev, Node next){
this.data=data;
this.prev=prev;
this.next=next;
}
}
so my problem is as follows: the line return temp.data rises an error:
Type mismatch - cannot convert from Instance to T.
What is wrong with this code?
I'd say that Node.data is a reference to an Instance object? If that is the case, the compiler can't automatically change an Instance to a T, because even though T is an Instance object (T extends Instance), any given Instance might not be a T.
The Java Generics tutorial explains it: http://docs.oracle.com/javase/tutorial/extra/generics/subtype.html
Also, in your List<T> class, you should be specifying Iterator and ListIterator as generic using Iterator<T> and ListIterator<T>, or else the compiler won't be able to handle the generics properly. Your Node reference also needs to be generic: Node<T>
Hence you should be using
private Node<T> current;
and
public T next() {
Node<T> temp=current;
current=current.next;
return temp.data;
}
The compiler will usually warn you when you're using a raw type for a generic class.
Did no one notice the bug:
public boolean hasNext() {
if(current==null)
return false;
return false;
}
This is an invariant. Unless I am missing something, the iterator will very quickly return 0 elements!

Java Generics 'Incompatible Type' Compile-Time Error

For a CS class I am writing a linked list implementation of a linked list interface created by my professor. The assignment requires us to use generics for the list. What I have created, I think, is pretty standard.
public class MyLinkedList<T> implements ADTListInterface {
...
private class Node<T> {
Node<T> head;
Node<T> prev;
public Node(int max) {
...
}
public void shift() {
...
Node<T> newNode = new Node<T>(this.max);
newNode.prev = head.prev;
...
}
}
...
}
At compile time following error is generated:
MyLinkedList.java:111: incompatible types
found : MyLinkedList<T>.Node<T>
required: MyLinkedList<T>.Node<T>
newNode.prev = head.prev;
This error has me very confused. Can anyone explain to me what the issue is?
Here is probably the problem:
private class Node<T> {
The <T> is causing extra problems. Because Node is an inner class, it doesn't need to declare its generic type again.
You should declare the Node class like below:
public class MyLinkedList<T> implements ADTListInterface {
...
private class Node {
Node head;
Node prev;
public Node(int max) {
...
}

Categories