Axel Finkel
Axel Finkel

Reputation: 45

Linked List using generics, getting "not applicable arguments for parameters" error

My Node class:

public class Node<T> 
{
    protected T data;
    protected Node<T> next;
    protected Node<T> previous;

    public Node()
    {
        this.data = null;
        this.next = null;
        this.previous = null;
    }

    public Node(T data)
    {
        this.data = data;
        this.next = null;
        this.previous = null;
    }

    public Node(T data, Node<T> next, Node<T> previous)
    {
        this.data = data;
        this.next = next;
        this.previous = previous;
    }

    public T getData() 
    {
        return data;
    }

    public void setData(T data) 
    {
        this.data = data;
    }

    public Node<T> getNext() 
    {
        return next;
    }

    public void setNext(Node<T> next) 
    {
        this.next = next;
    }

    public Node<T> getPrevious() 
    {
        return previous;
    }

    public void setPrevious(Node<T> previous) 
    {
        this.previous = previous;
    }
}

My LinkedList class:

public class LinkedList<T extends Node<T>>
{   
    private Node<T> head;
    private Node<T> tail;
    private Node<T> currNode;

    public LinkedList()
    {
        head = null;
        tail = null;
        currNode = null;
    }

    public LinkedList(Node<T> head)
    {
        this.head = head;
        tail = head;
        currNode = head;
    }

    public void resetHead()
    {
        currNode = head;
    }

    public void add(T data)
    {
        Node<T> newNode = new Node<T>(data);

        newNode.next = null;

        if(head == null)
        {
            head = newNode;
        }
        else
        {
           tail.next = newNode;
           newNode.previous = tail;
           tail = newNode;
        }

    }

    public void addHead(T data)
    {
        Node<T> newNode = new Node<T>(data);

        newNode.next = head;

        head.previous = newNode;

        head = newNode;
    }

    public void addAfter(T data, Node<T> previousNode)
    {
        Node<T> newNode = new Node<T>(data);

        newNode.next = previousNode.next;

        previousNode.next = newNode;
    }

    public void addBefore(T data, Node<T> nextNode)
    {
        Node<T> newNode = new Node<T>(data);

        newNode.next = nextNode;

        nextNode.previous = newNode;
    }

    public void delete(Node<T> nodeToDelete)
    {
        (nodeToDelete.getNext()).setPrevious(nodeToDelete.getPrevious());
        (nodeToDelete.getPrevious()).setNext(nodeToDelete.getNext());
        nodeToDelete.setNext(null);
        nodeToDelete.setPrevious(null);
    }

    public boolean hasNext()
    {
        if(head == null)
        {
            return false;
        }
        else if(currNode.next != null)
        {
            currNode = currNode.getNext();
            return true;
        }
        else
        {
            return false;
        }
    }

    public boolean hasPrevious()
    {
        if(tail == null)
        {
            return false;
        }
        else if(currNode.previous != null)
        {
            currNode = currNode.getPrevious();
            return true;
        }
        else
        {
            return false;
        }
    }

    public Node<T> getHead() 
    {
        return head;
    }

    public void setHead(Node<T> head) 
    {
        this.head = head;
    }

    public Node<T> getTail() 
    {
        return tail;
    }

    public void setTail(Node<T> tail) 
    {
        this.tail = tail;
    }

    public Node<T> getCurrNode() 
    {
        return currNode;
    }

    public void setCurrNode(Node<T> currNode) 
    {
        this.currNode = currNode;
    }
}

The error crops up when attempting to use any of the add/insert methods in LinkedList. For example, if I try to use the add(T data) method, like so: listOfChars.add('B');, I get the following error: The method add(Node) in the type LinkedList is not applicable for the arguments (char). What I expect it to do is to accept the data (in this case, the char 'B'), create a new node with 'B' as the data, and then put it in the linked list after the last node in the list. From my understanding, the method is expecting a Node instead of any generic data type, such as a char.

After doing some researching, I think somewhere in my TestLinkedList class, I have declared the LinkedList object incorrectly:

public class TestLinkedList 
{
    public static void main(String[]args)
    {
        Node<Character> n1 = new Node<Character>('A');

        LinkedList listOfChars = new LinkedList(n1);

        listOfChars.add('B');
    }
}

but I can't figure out how to declare it correctly. I've tried LinkedList<Character>, LinkedList<Node>, LinkedList<Node<T>>, and LinkedList<Node<Character>>, but none of them are correct. Any help would be appreciated as this is my first time using generics and I am just trying to learn how to apply it to a Linked List I've made.

Upvotes: 3

Views: 1572

Answers (6)

Todd Dunlap
Todd Dunlap

Reputation: 141

Create your LinkedList like this:

LinkedList<Character> listOfChars = new LinkedList<>(n1);

EDIT: M4ver1k is right that this alone won't fix it. I missed the part that Adam Arold pointed out. Adam's answer fixes the problem and should be accepted. My answer just prevents the LinkedList from being implicitly defined as a LinkedList<Object>.

.

Upvotes: -2

Alex D
Alex D

Reputation: 37

Ok, so your class declaration public class LinkedList<T extends Node<T>> is saying 'This is a class LinkedList parameterised by T where T is a subtype of Node<T>

This means if you wanted T = Character for example, you would need Character to be a subtype of Node<Character>, which doesn't really make sense.

You probably want to just parameterise your class by T eg public class LinkedList<T>

Then you can go LinkedList<Character> listOfChars = new LinkedList<Character>(n1)

or more succinctly LinkedList<Character> listOfChars = new LinkedList<>(n1) as the second generic parameter can be inferred

Upvotes: 1

Adam Arold
Adam Arold

Reputation: 30528

You simply have to rewrite LinkedList from

LinkedList<T extends Node<T>>

to

LinkedList<T>

since in the code of LinkedList you already state that you are using Node objects.

You can use it like this:

    public static void main(String[]args)
    {
        Node<Character> n1 = new Node<>('A');

        LinkedList<Character> listOfChars = new LinkedList<>(n1);

        listOfChars.add('B');
    }

Upvotes: 4

Ash
Ash

Reputation: 2602

I think its a combination of both Todd's and Adams answer

public class LinkedList<T extends Node<T>>

to

public class LinkedList<T>

and

LinkedList<Character> listOfChars = new LinkedList<>(n1);

Upvotes: 2

JT_
JT_

Reputation: 33

As you can infer from the error The method add(Node) in the type LinkedList is not applicable for the arguments (char) This is a type error, your add method expects a Node but in the main you call add with type character.

Your LinkedList class is expecting an object of type T extends Node. Which would imply a custom class that extends your Node object, however that is not what you are looking to use to add objects to the linkedlist.

Upvotes: 1

Emil Forslund
Emil Forslund

Reputation: 547

You need to fix two things. First, the class declaration of LinkedList says:

public class LinkedList<T extends Node<T>> {

which means that T has to be both a Node and the element of a Node. This doesn't work with Character since a Character is not an instance of Node. If you remove the constraint so that T can be any value, it works with Character.

public class LinkedList<T> {

Next you should add the generic part to the main file for the listOfChars as well:

LinkedList<Character> listOfChars = new LinkedList<Character>(n1);

Also make sure that you have imported the right LinkedList and not the java standard class.

Upvotes: 4

Related Questions