MetallicPriest
MetallicPriest

Reputation: 30765

Generic in Java throwing errors when methods are defined

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

Upvotes: 1

Views: 421

Answers (5)

Vinay Prajapati
Vinay Prajapati

Reputation: 7504

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.

Upvotes: 1

OneCricketeer
OneCricketeer

Reputation: 191743

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;

Upvotes: 1

Gaurav Gupta
Gaurav Gupta

Reputation: 142

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

Upvotes: 1

Eran
Eran

Reputation: 393811

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;
}

Upvotes: 1

Mohamed Anees A
Mohamed Anees A

Reputation: 4591

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;
}
}

Upvotes: 0

Related Questions