1

I am implementing a cyclic DoublyLinkedList data structure. Like a singly linked list, nodes in a doubly linked list have a reference to the next node, but unlike a singly linked list, nodes in a doubly linked list also have a reference to the previous node.

Additionally, because the list is "cyclic", the "next" reference in the last node in the list points to the first node in the list, and the "prev" reference in the first node in the list points to the last node in the list.

I need help starting my get method, I've been looking around and I couldn't find anything that could help me since I am working with a Generic Type . I need to return E and every other examples show me it with int as an example. Here is my code:

public class DoublyLinkedList<E>
{
private Node first;
private int size;

@SuppressWarnings("unchecked")
public void add(E value)
{
    if (first == null)
    {
        first = new Node(value, null, null);
        first.next = first;
        first.prev = first;
    }
    else
        {
        first.prev.next = new Node(value, first, first.prev);
        first.prev = first.prev.next;
    }
    size++;
}
private class Node<E>
{
    private E data;
    private Node next;
    private Node prev;

    public Node(E data, Node next, Node prev)
    {
        this.data = data;
        this.next = next;
        this.prev = prev;
    }
}
@SuppressWarnings("unchecked")
public void add(int index, E value)
{
    if (first.data == null)
    {
        throw new IndexOutOfBoundsException();
    } else if (index == 0)
    {
        first = new Node(value, first.next, first.prev);
    }
    else
        {
        Node current = first;
        for (int i = 0; i < index - 1; i++)
        {
            current = current.next;
        }
        current.next = new Node(value, current.next, current.prev);
    }
}
@SuppressWarnings("unchecked")
public void remove(int index)
{
    if (first.data == null)
    {
        throw new IndexOutOfBoundsException();
    }
    else if (index == 0)
    {
        first = first.next;
    }
    else
        {
            Node current = first.next;
            for (int i = 0; i < index - 1; i++)
        {
            current = current.next;
        }
        current.next = current.next.next;
    }
    size--;
}

I can't think of a way to get started on this, but basically what this method should do is return the element at the specified index in the list. If the index parameter is invalid, an IndexOutOfBoundsException should be thrown.

public E get(int index)
{

}

Also, my remove method isn't accurate, but I'll figure that one out myself, I just need help with my get method.

Adan Vivero
  • 422
  • 12
  • 36
  • The get function should be fairly easy. Since the class has a size parameter, if index >= size, it's an invalid index, so the code won't need a special check to see if advancing an node reference cycles around the list. If index == 0, return first.data. Else, make a copy of first, like "node = first", then advance node = node.next "index" times, and return node.data. – rcgldr Mar 18 '19 at 06:49
  • @rcgldr that wouldn't work considering that first.data is not a type E. It's an object. What I am merely saying is that I don't know how to necessarily convert it to an E. – Adan Vivero Mar 18 '19 at 15:08
  • @rcgldr private E data is inside a private class, which makes it hard to access to, but my instructions were clear to have it set up like that. – Adan Vivero Mar 18 '19 at 15:08
  • According to my rubric, I must leave the node class as it is. – Adan Vivero Mar 18 '19 at 18:38
  • @rcgldr I figured it out. – Adan Vivero Mar 19 '19 at 20:52
  • I deleted my prior comment. If add() can access node private members `next` and `prev`, then a get() function should be able to access private member `data`. The main issue would be the syntax for the generic type. – rcgldr Mar 19 '19 at 22:26

3 Answers3

2

I figured it out, I'm just shocked that I wasn't getting any responses for this question. Either way, I am going to write some comments so it kind of guides future viewers who are struggling with this.

@SuppressWarnings("unchecked")
public E get(int index)
{
    if(index < 0) //The index needs to be above 0.
    {
        throw new IndexOutOfBoundsException(); 
    }
    if(index > size) //Since we're going to run a for loop, we need to make sure the index doesn't go past the size of the list. 
    {
        throw new IndexOutOfBoundsException();
    }
    Node current = first; //We want to create another node to perform this method.
    for (int i = 0; i < index; i++) //We are going to set i to 0 and loop around this for loop until we reach the index. 
    {
        current = current.next;
    }
    return (E) current.data; //Since we are working with generics, we need to return a type E, and it needs to be in parenthesis so it gets that object.
}
Adan Vivero
  • 422
  • 12
  • 36
0

Another problem I sort of had was that in my Node Class I had the in there, when I could've moved on without it. Lets update it to be

private class Node
{
    private E data;
    private Node next;
    private Node prev;

    public Node(E data, Node next, Node prev)
    {
        this.data = data;
        this.next = next;
        this.prev = prev;
    }
}

And now my getMethod() will be as follows:

@SuppressWarnings("unchecked")
public E get(int index)
{
    if(index < 0)
    {
        throw new IndexOutOfBoundsException();
    }
    if(index > size)
    {
        throw new IndexOutOfBoundsException();
    }
    Node current = first;
    for (int i = 0; i < index; i++)
    {
        current = current.next;
    }
    return current.data;
}
Adan Vivero
  • 422
  • 12
  • 36
0

You can also use a hash map, and you will get the data on constant time

public T get(int position){
    Node<T> node = map.get(position);
    T dat = node.getData();
    return dat;
}
Brydenr
  • 798
  • 1
  • 19
  • 30
  • Hi Jorge, in my mind using a backing `HashMap` to store data defeats the purpose of using a `DoublyLinkedList` in the first place. – Brydenr Dec 13 '19 at 17:21