I'm working with a LinkedList of customLinkedLists and I'm having some problems with the implementation of my AddFirst method.
Here's the method,
public void addFirst(GenericType data)
{
Node<GenericType> toAdd = new Node<GenericType>(data);
if(sizeCounter != 0)
{
toAdd.next = head;
head = toAdd;
sizeCounter++;
} else {
head = toAdd;
tail = toAdd;
toAdd.next = null;
sizeCounter++;
}
}
The problem is this increments the size correctly every time i call it, but when I try to print out the values, it throws a null pointer exception.
I know there's a problem in the way I'm setting the head/tail pointer but I cant figure out what it is exactly.
EDIT:
Basically I have a OuterList and a custom LinkedList class.
in the outer list class, i have an object that makes:
LinkedList<CustomList<GenericType>> oList = new LinkedList<CustomList<GenericType>>;
//method add in OuterList class that calls addFirst in customLinkedClass
public void add(GenericType x){
oList.get(0).addFirst(x);
}
//Prints the List
public void print(){
for(int i=0; i<oList.size(); i++){
for(int j=0; j<oList.get(i).size(); j++){
// first .get() is for the oList to get the first customLinkedList.
// second .get() returns the value of the Node in the customLinkedList
System.out.println(oList.get(i).get(j));
}
}
When I try to dump after adding an item it throws a null pointer. When I create the customLinkedList, is set head.next = tail. Could that be the cause of the problem? I do not see why it would be giving me errors
EDIT 2:
Stack Trace:
Exception in thread "main" java.lang.NullPointerException
at squarelist.CustomList.get(CustomList.java:187)
at squarelist.OuterList.dump(OuterList.java:94)
at squarelist.OuterList.main(OuterList.java:106)
Line it occurs at:
public GenericType get(int index){ return getNodeAt(index).value; }
getNodeAt() function:
private Node<GenericType> getNodeAt( int index ){
Node<GenericType> p = null;
p = head.next;
for( int i = 0; i < index; i++ ){
p = p.next;
}
return p;
}
Change this :
head = add;
tail = add;
to this :
head = toAdd;
tail = toAdd;
in the else block
EDIT
After posting the stack trace, the problem is that you are returning null from the getNodeAt method.
Let's say that you have only one element in the list; then p = head.next; will be null and you are returning that value.
Try setting p=head instead
Related
I want to add a method add(int index, E element) in Java, that inserts a specified element at a specified index in the list and shifts the element currently at that position (if any) and any subsequent elements to the right (adds one to their indices). But I guess something is wrong with the indices in my code in the for-loop. Any ideas how to solve it?
public class SingleLinkedList<E> implements ISingleLinkedList<E> {
Node head;
int size = 0;
#Override
public void add(int index, E element) throws IndexOutOfBoundsException {
Node newNode = new Node(element);
if(head == null && index == 0) {
head = newNode;
}
else if (index == 0 && head != null) {
Node tempNode = new Node(element);
tempNode.setmNextNode(head);
head = tempNode;
}
else {
Node tempNode = head;
for(int i = 1; i<index; i++) {
tempNode = tempNode.getmNextNode();
}
/**Node newNode = new Node(element);**/
newNode.setmNextNode(tempNode);
tempNode.setmNextNode(newNode);
}
size++;
}
}
My code for the Node class is:
public class Node<E> {
private E mElement;
private Node<E> mNextNode;
Node(E data) {
this.setmElement(data);
}
public E getmElement() {
return this.mElement;
}
public void setmElement(E element) {
this.mElement = element;
}
public Node<E> getmNextNode()
{
return this.mNextNode;
}
public void setmNextNode(Node<E> node)
{
this.mNextNode = node;
}
The problem is that I have a JUnit test that fails when adding this method and I do not know what more I need to add in order to pass the test.
#Test
public void testAddWithIndexesToListWith5Elements() {
int listSize = 5;
// First create an ArrayList with string elements that constitutes the test data
ArrayList<Object> arrayOfTestData = generateArrayOfTestData(listSize);
// Then create a single linked list consisting of the elements of the ArrayList
ISingleLinkedList<Object> sll = createSingleLinkedListOfTestData(arrayOfTestData);
// Add new elements first, in the middle and last to the ArrayList of test data
// and the single linked list
try {
arrayOfTestData.add(0, 42);
arrayOfTestData.add(3, "addedElement1");
arrayOfTestData.add(7, "addedElement2");
sll.add(0, 42);
sll.add(3, "addedElement1");
sll.add(7, "addedElement2");
}
catch (Exception e) {
fail("testAddWithIndexesToListWith5Elements - add() method failed");
}
// Check that the contents are equal
for (int i = 0; i < sll.size(); i++) {
assertEquals(arrayOfTestData.get(i), sll.get(i));
}
}
newNode.setmNextNode(tempNode);
tempNode.setmNextNode(newNode);
This is just going to create a cycle. It looks like your newNode should point to tempNode.getmNextNode() or something along those lines.
Your question is pretty unclear but I think I can see a problem.
If index is not 0, the you will iterate through the nodes until the index is reached.
If there are not enough elements in the list, you will reach the end of the list before the index where you want to insert the element.
In this case,
tempNode = tempNode.getmNextNode();
will set tempNode to null.
In the next iteration, this line will throw a NullPointerException.
You can bypass this issue by testing if tempNode.getmNextNode(); is null.
If that is the case, the element will just be inserted at the end/that point or will not be inserted.
I'm attempting to create an array of linked list which will deal with hash value collisions. I have an array of an objects which I have tried to store the linkedList but it doesn't seem to work. Is there something I'm doing wrong, or is there a more efficient route I should take.
This is the error I get when running my code.
Exception in thread "main" java.lang.ArrayStoreException: linkedList
at p7b.Insert(p7b.java:57)
at p7b.main(p7b.java:31)
Here is my method
public static void Insert(int hashVal, String key,int[] arrayNums, Object[] arrayString){
Node newNode = new Node(key,null);
linkedList list = new linkedList();
if (arrayString[hashVal] == null){
arrayString[hashVal] = list;
}
Here is the linkedList code:
public class linkedList{
private Node head;
private int size;
public linkedList(){
size = 0;
head = null;
}//end default constructor
public boolean isEmpty(){
return size == 0;
}//end isEmpty
public int size(){
return size;
}//end size
protected Node find(int index){
Node curr = head;
for(int skip = 0; skip < index; skip++){
curr = curr.getNext();
}//end for
return curr;
}//end find
public Object get(int index){
if (index >=0 && index < size) {
// get reference to node, then data in node
Node curr = find(index);
Object dataItem = curr.item();
System.out.println(dataItem);
return dataItem;
}
else
return "error";
}//end get
public void add(int index, String item){
if(index>= 0 && index < size+1){
if(index == 0) {
//insert the new node containing item at
//beginning of list
Node newNode = new Node(item,head);
head = newNode;
head.setNext(head);//--------------------
}
else {
Node prev = find(index-1);
//insert the new node containing item after
//the node that prev references
Node newNode = new Node(item,head.getNext()); //changed prev to head
head.setNext(newNode); //prev.next = newNode --//changed prev to ead
head = newNode;
}//end if
}
sizeplus();
/*if(index == 16){//fffff
for(int i = 0; i < 50; i++){
System.out.println(head.item());-------------EXR
head = head.getNext();
System.out.println("----------");
}//ifffffff
}
*/
}//end add
public int sizeplus(){
size+=1;
return size;
}
public void remove(int index){
int num = index;
while(size>0){
//System.out.println("strt");
if(index>= 0 /*&& index < size*/){
if(index == 0) {
//delete the first node from the list
System.out.println("REMOVED :"+head.item());//----------------EXR
head = head.getNext();
}
else {
Node prev = find(index-1);
// delete the node after the node that prev
//references, save regerence to node
Node curr = prev.getNext();
System.out.println(curr.item());
if(size > 1){
}
else{
System.out.print("is the last one left");
}
prev.setNext(curr.getNext());
curr = prev.getNext();
index+=num-1;
}//end if
size--;
//System.out.println(size+" <-size || index-> " +index);
}//end if
}
}//end remove
public Node getH(){
return head;
}
}//end class
ALSO: how would i change from linked list to the next
here is what i tried.
linkedList list = new linkedList();
list = arrayString[i];
p7b.java:44: error: incompatible types
list = arrayString[i];
^
required: linkedList
found: Object
1 error
From your main method :
Object[] arrayString = new String[40];
...
Insert(hashVal,key,arrayNums,arrayString);
You are passing a String array to your method.
Therefore you can't put linkedList instances in this array.
If you want this array to contain linkedList instances, change the code to :
Object[] arrayString = new linkedList[40];
...
Insert(hashVal,key,arrayNums,arrayString);
or even better :
linkedList[] arrayString = new linkedList[40];
...
Insert(hashVal,key,arrayNums,arrayString);
and change the signature of Insert to accept a linkedList[] instead of Object[].
Here's the culprit:
Object[] arrayString = new String[40];
You're claiming that it's an Object[], but it's actually backed by a String[] instead. Java can't make the determination at compile time that you're not going to be able to store any old Object into that array, so it blows up at run time.
What you should do is type the array correctly - if it's going to hold linkedList entities, it should be linkedList entities.
linkedList[] linkedLists = new linkedList[40];
More specifically, you are using the array in a lot of different places. Be consistent with its usage.
Having a few thoughts about your code: it's not...correct. You're creating a linked list, right? There's no reason to use arrays unless the list itself is backed by them.
I can't vouch for the correctness of your linkedList.add method right now, but you don't want to use arrays for this at all. Create a single instance of a linked list outside of that method and store all of the data you care about in it.
public static void insert(String key, int index, linkedList list) {
list.add(index, key);
}
(As a general thought, linked lists don't have index positions that you simply insert into, so the index portion is completely superfluous.)
I'm trying to add a new Node to the end of my linked list but it doesn't seem to be doing anything. It adds the first element because it's a special case but then ignores all of the other assignments when I step through the debugging.
Here's the test I'm running:
#Test
public void testInsertElement()
{
PriorityList<String> list = new LinkedPriorityList<String>();
list.insertElementAt(0, "first");
list.insertElementAt(1, "second");
list.insertElementAt(2, "third");
assertEquals("first" , list.getElementAt(0));
assertEquals("second", list.getElementAt(1));
assertEquals("third" , list.getElementAt(2));
}
It fails on the second assertion because nothing is added after the first.
Here's the constructor for the Node Objects:
public class LinkedPriorityList<E> implements PriorityList<E> {
private class Node
{
private E data;
private Node next;
public Node(E element)
{
data = element;
next = null;
}
}
And finally the code that is failing on me:
public void insertElementAt(int index, E element) throws IllegalArgumentException
{
if(index>size() || index<0) //can only be between 0 and size()
throw new IllegalArgumentException();
if(size()==0)
first = new Node(element); //adding the first element. This works
else
{
if(index == size()) //if an element is being added to the end
{
Node ref = first; //assigning ref to the first element of the list
for(;ref!=null; ref = ref.next); //stepping through the list until ref is null
ref = new Node(element); //assigning the null reference a new Node. Doesn't assign
}
else //if an element is being inserted in the list. untested...
{
Node ref = first;
Node temp = new Node(element);
for(int i=1; i<index; i++)
ref = ref.next;
temp = ref.next;
ref = temp;
}
}
size++; //keeping track of how many elements in list
}
I think this works but if you want the get method too, here it is:
public E getElementAt(int index) throws IllegalArgumentException
{
if(index>=size() || index<0)
throw new IllegalArgumentException();
Node ref = first;
for(int i=0; i<index; i++)
ref = ref.next;
return ref.data;
}
When index == size, you want to create a new node, find the last node in the list, and assign the new node to its next pointer.
The last node is the one whose next pointer is null.
This should be enough to let you implement the algorithm by yourself.
This is probably what you meant to do:
for(; ref.next != null; ref = ref.next) {
/* intentionally empty */
}
ref.next = new Node(element);
Note that I'm both testing and assigning ref.next, not ref itself.
You need a temp node when adding at the end too (to keep track of the last element)
if (index == size())
{
Node ref = first, temp = first;
for (; ref != null; temp = ref, ref = ref.next);
temp.next = new Node(element);
}
By just assigning the new Node to ref; it doesn't link it to the current last node's next.
import javax.swing.JOptionPane;
public class RotateArrayCircularLL
{
private Node head=null;
public void init()
{
int choice = 0;
while (choice != -1){
choice = Integer.parseInt(JOptionPane.showInputDialog("Enter -1 to stop loop, 1 to continue"));
if(choice == -1)
break;
inputNum();
}
printList();
}
public void inputNum()
{
Node n;
Node temp;
int k;
k = Integer.parseInt(JOptionPane.showInputDialog(null,"Enter a number:"));
n = new Node(k);
if (head == null) {
head = n;
} else {
temp = head;
while (temp.getNext() != null)
temp = temp.getNext();
temp.setNext(n);
}
}
public void printList()
{
Node temp = head;
int count = Integer.parseInt(JOptionPane.showInputDialog("Enter the value to shift to the right"));
for (int i = 1; i <= count; i++) // Rotates the head
temp = temp.getNext();
for (Node c = temp; c != null && c.getNext() != head; c= c.getNext()){ // Prints the new LL
System.out.print(c.getInfo());
}
}
}
I get an NPE during the second for loop. I understand that it is giving me a NPE because I reach the end of the list, but how can I stop it from doing this?
It appears from the behavior you are seeing that one of the nodes in your linked list is returning null instead of the next element of the list. At a guess, I'd suggest that the last node of your list is probably not pointing to the first node of your list. Hence as Hovercraft Full Of Eels suggests, you don't really have a properly circular linked list. If you can post the code showing how temp is populated, it may be possible to give a more concrete solution to your issue. Otherwise, you need to treat the case where getNext() returns null as a special case and ensure that you instead get the first element from the initial list.
I am trying to run a test for a getPrevious() method in JUnit.
public void getPrev(){
for (int i = 0; i < 1000; i++) {
list.add(i);
}
list.reset();
for (int i = 999; i >= 0; i--) {
int info = list.getPrevious();
assertEquals(i, info);
}
}
Every other method seem to work, except for this one. After running some printing tests, I realized that the reset method
...reset(){
if (list != null)
location = list.getPrev();//returns the last node's previous node -- head node.
}
(which should make the location node the head node) was not returning the correct information. It returned null instead of the head node.
Thus, my logic led me to believe that the add method was not working as it should be. And this is also my question. I have been trying multiple things to see where the error is but nothing seem to work. I am looking to see if anyone can help spot the logic error in this code.
public void add(Object elem) {
LLNode<T> newNode = new LLNode(elem);
if(list == null){
tail = list = newNode;
}
list.setPrev(newNode);
newNode.setNext(list);
newNode.setPrev(tail);
tail.setNext(newNode);
list = newNode;
size++;
}
Try This
public int add(Object elem) {
Node node = new Node(elem);
if (head == null) {
head = node;
} else {
tail.setNext(node);
node.setPrevious(tail);
}
tail = node;
return value;
}