How can I delete a value from a Linked List? - java

I am working on a project for my Data Structures class that asks me to write a class to implement a linked list of ints.
Use an inner class for the Node.
Include the methods below.
Write a tester to enable you to test all of the methods with whatever data you want in any order.
I have to create a method called "public boolean delete(int item)". This method is meant to "Delete an item from the list and return a Boolean indicating whether or not the item was deleted" I have my code for this method down below. However, when I try to delete an item from my list nothing changes. The item that I tried to delete is still there but it returns true that an item was deleted. Does someone know what I did wrong in my code and how to fix it?
import java.util.Random;
import java.util.Scanner;
public class LinkedListOfInts {
Node head;
Node tail;
private class Node {
int value;
Node nextNode;
public Node(int value, Node nextNode) {
this.value = value;
this.nextNode = nextNode;
}
}
public LinkedListOfInts(LinkedListOfInts other) {
Node tail = null;
for (Node n = other.head; n != null; n = n.nextNode) {
if (tail == null)
this.head = tail = new Node(n.value, null);
else {
tail.nextNode = new Node(n.value, null);
tail = tail.nextNode;
}
}
}
public LinkedListOfInts(int[] other) {
Node[] nodes = new Node[other.length];
for (int index = 0; index < other.length; index++) {
nodes[index] = new Node(other[index], null);
if (index > 0) {
nodes[index - 1].nextNode = nodes[index];
}
}
head = nodes[0];
}
public LinkedListOfInts(int N, int low, int high) {
Random random = new Random();
for (int i = 0; i < N; i++)
this.addToFront(random.nextInt(high - low) + low);
}
public void addToFront(int x) {
head = new Node(x, head);
}
public int deleteFromFront() {
int headValue = -1;
if (head == null)
return headValue;
else {
if (head == tail) {
head = null;
tail = null;
} else {
headValue = head.value;
head = head.nextNode;
}
}
return headValue;
}
public boolean delete(int item) {
Node previous = null;
for (Node ptr = head; ptr != null; ptr = ptr.nextNode) {
if (ptr.value == item) {
if (previous != null) {
previous = ptr;
} else
deleteFromFront();
return true;
}
previous = ptr;
}
return false;
}
public String toString() {
String result = " ";
for (Node ptr = head; ptr != null; ptr = ptr.nextNode)
result += ptr.value + " ";
return result;
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
LinkedListOfInts list = new LinkedListOfInts(10, 1, 20);
LinkedListOfInts copy = new LinkedListOfInts(list);
boolean done = false;
while (!done) {
System.out.println("1. Delete an Item in the Array");
System.out.println("2. toString");
switch (input.nextInt()) {
case 11:
System.out.println("Delete an Item in the Array");
System.out.println(list.delete(input.nextInt()));
break;
case 12:
System.out.println("toString");
System.out.println(list.toString());
break;
}
}
}
}

Because local variable is local. Let's go through your delete method:
Node previous = null;
This declares a new local variable named previous, which currently points at nothing. Like all local variables, and like all non-primitive variables, [A] this thing will poof out of existence once the method terminates, and [B] it's a pointer. (in java parlance, a reference). It's like an address on a slate, it's not a house. It's the address to a house.
previous = ptr;
This erases what is on your slate and copies over the house address. It doesn't copy the house, nor does it have any effect on the house whose address was on your slate before wiping out that address and copying the address of whatever the 'ptr' slate's got on it.
... method ends
... and there previous goes. In the trashcan.
a.b is java-ese for: Drive over to the address on slate 'a', and ask the house to 'b' (or change something about the house, if you're messing with fields instead of calling methods).
So, pointer = foo accomplishes nothing. head.something = foo, that does something, now you're driving. You have to drive somewhere, or change one of your fields, for this code to do anything.
previous.nextNode = ptr.nextNode; is more what you're looking for. previous is a copy of the address of the node you visited before. Changing the address on your little note isn't going to accomplish anything, you want to drive over there. previous.nextNode is: Find the scribbled address on the piece of paper named 'previous' and drive over there. Go in the house and find the box labelled 'nextNode'. Open the box, you'll find a note with an address in it. Take that address, scratch it out, and write a new address on it.
Now if somebody else, with a different piece of paper with the same address on it, drives on over and pulls that box out, they'll see what you changed.
In java, just about everthing is an address scribbled on a note and not the object itself. (the only exceptions are primitives: int, long, double, float, boolean, char, short, byte).

Related

How to create a linked list in java without importing linked lists

i am a CS student in college and i am having trouble with this project where i am supoosed to create a linked list using nodes without importing linked lists, as well as doing a some methods with the list. i am a beginner when it comes to coding, so assume i know nothing, because that is probably the case lol.
import java.io.*;
import java.lang.*;
public class List {
public int listCount = 0;
public char[] linkedList;
public List() throws FileNotFoundException {
}
public List(char[] array) throws FileNotFoundException {
if (array.length == 1) {
Node head = new Node(array[0]);
} else if (array.length > 1) {
Node head = new Node(array[0]);
Node traverse = head;
for (int i = 1; i < array.length; i++) {
while (traverse.nextNode != null) {
traverse = traverse.nextNode;
}
traverse.nextNode = new Node(array[i]);
listCount++;
}
}
}
public List(String w) throws FileNotFoundException {
char[] array2 = new char[w.length()];
for (int i = 0; i < w.length(); i++) {
array2[i] = w.charAt(i);
}
List str = new List(array2);
}
/* Find the character at a index
#param int index
return the character at the chosen index
*/
public char charAt(int index) throws IndexOutOfBoundsException {
char results = linkedList[0];
if (index < linkedList.length && index >= 0) {
results = linkedList[index];
}
return results;
}
public String concat(int index1, int index2) {
return null;
}
/* Determine if the list is empty
return whether the given conditions are true or false
*/
public boolean isEmpty() {
for (int i = 0; i < linkedList.length; i++) {
if (!linkedList.equals(null)) {
System.out.println("This list is not empty");
return false;
}
}
System.out.println("List is empty");
return true;
}
/* Determine the size of the list
return the size of the list
*/
public int size() {
return listCount;
}
/* Create a new String between 2 index's including the start and end index
#param beginIndex is the starting point of the new String
#endIndex is the ending point of new String
return the new String
*/
public String subString(int beginIndex, int endIndex) {
return null;
}
public void insert(Object x) throws IndexOutOfBoundsException {
if (listCount > 100 || listCount < 0) {
throw new IndexOutOfBoundsException("Bag is too large");
} else {
this.linkedList[listCount] = (char) x;
listCount++;
}
}
}
i appreciate any help or pointers ahead of time. we are using a separate node, helper, and driver class as well as a .txt file to assign into my list. i am stuck on the concat and substring methods too, but i want to make sure i am getting the framework correct first. thank you again.
If i understand your question correctly, you are asking how to access a specific type without importing it.
Imports are required to identify which type is referenced when it is used by its simple name. To reference a type without declaring it in the imports you need to use its fully qualified name. For instance
java.util.List<String> someList = new java.util.ArrayList<>();
works without importing List and ArrayList because by declaring the package the class is in it is clear which class is being referenced.
I'll try to do the code later, but here is a book that i found that may help you.
https://cin.ufpe.br/~grm/downloads/Data_Structures_and_Algorithms_in_Java.pdf
I bought a book about DATA STRUCTURE from Pearson company, and it's really a good book, but i don't remember much, it's something like this, that i did in a hurry:
public class List {
private Node head = null;
private Node foot = null;
private Node newNode = null;
private Node auxNode = null;
public List() {
this.head = new Node();
this.foot = new Node();
}
public class Node {
private int adress;
private Node nextNode;
}
public void add(int value) {
this.newNode = new Node();
newNode.adress = value;
if (head == null) {
// Head of the list receive the values of the NEW NODE, so the head of the list
// is not null enymore
head = newNode;
head.nextNode = null;
} else {
// In this case Head is not null
/*The auxiliary node will receive the head and the new Node will become the new Head from the list*/
auxNode = new Node();
auxNode = head;
/*
while(auxNode.nextNode != null ) {
}
auxNode = head;
//head of the list is empty, so we can add the new node
head = newNode;//Here the new node is empty because was transfered to the head
head.nextNode = auxNode; //The head of the list receive the old node that used to be the head
if (head.nextNode == null) {
head.nextNode = newNode;
} else if (head.nextNode != null) {
}*/
}
}
}
```
I hope this help you to get some lead

What's wrong with sorted set code? My output should match sample

Can anyone help on what's wrong with my code? Only the first input number shows up when I run it (it doesn't create a sorted list), the delete command isn't working, and the 'true' 'false' in exists command doesn't show up. My output should match the given sample I put at the end.
The areas I had to fill in to make the code work are the areas after the TODOTODOTODO symbols which would be 44-61, 75-83, 97-105. I'm not sure where I went wrong in those areas and why it is not working correctly to give the desired output?
import java.util.Scanner;
// Defines the a Sorted Set collection and implements a driver program in main
public class SortedSet {
// Define a basic element of a linked list
private class LinkedNode {
int x; // Value stored in the node
LinkedNode next; // Reference to the next node in the list
}
LinkedNode front = null; // Reference to the front of the singly linked list
// Adds the integer x to the collection.
// The resulting collection is sorted in increasing order and
// does not contain any duplicate values.
public void add(int x) {
// Initialize a new node to be added to the collection
LinkedNode newNode = new LinkedNode();
LinkedNode cur = front;
newNode.x = x;
// Check if list is empty
if (cur == null) {
front = newNode;
}
// If list is not empty, check if node should be placed in front
else if (front != null) {
if (newNode.x < front.x) {
newNode.next = front;
front = newNode;
}
// If not in front, check for the middle or the end, or duplicate.
else {
// <TODO><TODO><TODO>
LinkedNode temp = cur;
LinkedNode prev = cur;
int middle = x;
while (temp != null) {
if(temp.x > newNode.x) {
middle = 1;
newNode.next = temp;
prev.next = newNode;
}
prev = temp;
temp = temp.next;
}
if (middle == 0) {
prev = newNode;
}
}
}
}
// Deletes the integer x from the sorted set.
// The remaining collection remains sorted and without duplicates.
public void delete(int x){
// Declare a new reference and initialize it to the front of the list
LinkedNode cur = front;
// Check if list is empty
if (front == null) {
System.out.print("There is nothing to delete!");
} else { // Not empty
// Go through list, checking whether node is in the list, and delete if found
// <TODO><TODO><TODO>
LinkedNode prev = new LinkedNode();
while (cur.x != x && cur != null) {
prev = cur;
cur = cur.next;
}
if (cur != null)
prev.next = cur.next;
}
}
// Returns true if the integer x exists in the sorted set and false otherwise.
public void exists(int x) {
// Declare a new reference and initialize it to the front of the list
LinkedNode cur = front;
// Check if list is empty.
if (front == null) {
System.out.println("false");
}
// If not empty, check for the node.
// <TODO><TODO><TODO>
else {
while (cur != null) {
if (cur.x==x)
return;
cur=cur.next;
}
return;
}
}
// Returns a string representing the sorted set as a space separated list.
public String toString() {
String s = "";
LinkedNode cur = front;
while (cur!=null) {
s+= cur.x + " ";
cur = cur.next;
}
return s;
}
// Driver method
public static void main(String[] args) {
// Declare variables
SortedSet sortedSet = new SortedSet();
Scanner scan = new Scanner(System.in);
String[] tokens;
String command;
int num;
// Print header info
System.out.println("Programming Fundamentals\n"
+ "NAME: Andres Reyes\n"
+ "PROGRAMMING ASSIGNMENT 4\n");
// Enter command loop
while (true) {
// Prompt the user for a command
System.out.print("Enter command: ");
String input = scan.nextLine();
// Parse input
if (input.equals("q")) break; // user quits
tokens = input.split("\\s");
if (tokens.length < 2) continue; // invalid input
command = tokens[0];
num = Integer.parseInt(tokens[1]);
// Execute command
if (command.equals("add")){
sortedSet.add(num);
System.out.println(sortedSet);
} else if (command.equals("del")) {
sortedSet.delete(num);
System.out.println(sortedSet);
} else if (command.equals("exists")) {
sortedSet.exists(num);
} else {
System.out.print("Command does not exist");
}
}
System.out.println("\nGood bye!");
}
}
I made following changes in the add-function and they got it working for me:
// If not in front, check for the middle or the end, or duplicate.
else {
// <TODO><TODO><TODO>
LinkedNode temp = cur.next; // start at cur.next as your temp-variable
LinkedNode prev = cur;
int middle = 0; // set middle to 0
while (temp != null) {
if(temp.x > newNode.x) {
middle = 1;
newNode.next = temp;
prev.next = newNode;
}
prev = temp;
temp = temp.next;
}
if (middle == 0) {
// add node to the end
prev.next = newNode;
}
}
}
You have to start at cur.next as your temp-variable.
As far as I can see, you're not yet checking if there are any duplicate values in your list.
Edit: I didn't work on the exists-method, which is not giving you any output at the moment. The problem is simply that you're generating any output while you're checking if a value exists in your list. You could either write a System.out.print which prints "true" in case the value was found or "false" in case if wasn't. Or you change the return type of the exists-function to boolean, return a boolean according to the result and print the return value.
It might also help you to visualize a linked list to unterstand why you have to change the temp-variable to cur.next. I think https://www.tutorialspoint.com/data_structures_algorithms/linked_lists_algorithm.htm gives a good explaination of the insertion process.
I can give you some hints. The main problem I see with this code is that you really need a reference to the start of the LinkedList (the head) would be the only way to print the list and check for duplicates.
The following should be added to your class
LinkedList head = null; //start of the list
Then you have to update your toString() or you will never print the correct elements in your list no matter what you do. Try this:
public String toString(){
StringBuilder output = new StringBuilder();
LinkedNode current = head;
while(current != null){
output.append(current.x).append(" ");
current = current.next;
}
return output.toString();
}
You have to be really careful when you are appending to a String in a loop because Strings are immutable. Everytime you are appending to a list you are creating a new String. Instead, use StringBuilder.
//s+= cur.x + " ";
Your add method should handle the following cases:
Case 1: List is empty: ( don't forget to set ref to head)
Case 2: new element is great than front of list
Case 3: new element is less than current head
Case 4: new element is less than current and greater than head

Passing object in Dlist.

The line "if (l.head.item != 9" gave me the error it said something like object is not compatible with int. I am really confused on why is that? How to fix it?
/DListNode1/
/* DListNode1.java */
public class DListNode1 {
public Object item;
// public short[][] colorVal;
public DListNode1 prev;
public DListNode1 next;
DListNode1() {
item = 0;
prev = null;
next = null;
}
DListNode1(Object i) {
item = i;
prev = null;
next = null;
}
}
//////////////
/* Double linked list */
public class DList1 {
protected DListNode1 head;
protected DListNode1 tail;
protected long size;
public DList1() {
head = null;
tail = null;
size = 0;
}
public DList1(Object a) {
head = new DListNode1();
tail = head;
head.item = a;
size = 1;
}
public DList1(Object a, Object b) {
head = new DListNode1();
head.item = a;
tail = new DListNode1();
tail.item = b;
head.next = tail;
tail.prev = head;
size = 2;
}
public void insertFront(Object i) {
DListNode1 temp = new DListNode1(i);
if (size == 0) {
head = temp;
tail = temp;
}
else {
temp.next = head;
head.prev = temp;
head = temp;
} size++;
}
public void removeFront() {
if (size == 0) {
return;
}
else if (size == 1) {
head = null;
tail = null;
size--;
}
else {
head = head.next;
head.prev = null;
size--;
}
}
public String toString() {
String result = "[ ";
DListNode1 current = head;
while (current != null) {
result = result + current.item + " ";
current = current.next;
}
return result + "]";
}
/////////////
public static void main(String[] args) {
DList1 l = new DList1();
l.insertFront(9);
if (l.head.item != 9) {
System.out.println("head.item is wrong.");
As others have pointed out, the problem is that the type of l.head.item is Object, and you can't compare that with an int using != or ==.
Options:
Cast l.head.item to Integer or int:
// This could be done in one step if you wanted
int headValue = (int) l.head.item;
if (headValue != 9)
Or
// This could be done in one step if you wanted
Integer headValue = (Integer) l.head.item;
if (headValue != 9)
Or you could do it inline:
if ((int) l.head.item != 9)
Use equals instead, which will automatically box the int to an Integer.
if (!head.equals(9))
Make your type generic instead, so you'd have a DListNode1<Integer>, and you could then be certain that all node values were Integer references (or null), and the != check would automatically unbox the Integer to an int and work.
Personally I'd definitely make this generic, but my guess is that you're relatively new to Java, and might not want to start with generics just yet.
Note that there's a difference between using equals and performing the unboxing: if the value of l.head.item is a reference to a non-Integer object, the first approach will throw a ClassCastException and the second will just go into the body of the if statement (as a string is not equal to 9, for example). Which of those is preferable depends on what you're trying to achieve in your bigger program: if it's entirely reasonable for your list to contain non-integers, you should use the equals check; if it actually indicates a programming error, then an exception is preferable as it alerts you to the error more quickly and stops your program from proceeding with invalid assumptions.
In both cases if l.head.item is null, you'll get a NullPointerException. This could be "fixed" using:
if (!Integer.valueOf(9).equals(l.head.item))
... but again it depends on what you want your code to do if the value is null.
Because a DListNode1.item is an Object not an Integer. Try casting to a Integer and compare to an Integer (9)
Compare using equals method.'==' will compare the refrence.
if(l.head.item.equals(new Integer(9))==false)
It will give you error because int is primitive:
Incompatible operand types Object and int
Change your code to:
if (!l.head.item.equals(new Integer(9))) {
Hope this helps.

Using recursion for a custom linkedlist

For Homework I was told to write the insert method(in order) of a custom linked list. I wrote the base case, but I still don't understand the recursion case. I know I just asked how to write the contain method and someone helped me out, but in that case I did not have to do any modifications to the list like on this method. Please help me understand what is causing my linked list to override and if there is an easier way to simplify my code.
Here is my code:
public class OrderedList {
private Node first;
//Constructor
public OrderedList() {
this.first = null;
}
//Return the number of items in the list
public int size() {
int counter = 0;
Node pointer = this.first;
while (pointer != null) {
counter++;
pointer = pointer.next;
}
return counter;
}
//Return an array of copies of the stored elements
public Comparable[] getStore() {
Comparable[] elements = new Comparable[size()];
Node pointer = this.first;
if (this.first == null) {
return elements;
} else {
int i = 0;
while (pointer != null) {
elements[i] = pointer.data;
pointer = pointer.next;
i++;
}
return elements;
}
}
//true iff item matches a stored element
//Recursive
public boolean contains(Comparable item) {
return containsHelper(this.first, item);
}
private boolean containsHelper(Node node, Comparable item) {
//base case
if (node == null) {
return false;
} else {
if (node.data.compareTo(item) == 0) {
return true;
}
return containsHelper(node.next, item);
}
}
//Add item preserving the order of the elements
//Recursive
public void insert(Comparable item) {
insertHelper(this.first, item);
}
public void insertHelper(Node pointer, Comparable item) {
//Base case
Node store = new Node(item);
if (pointer == null) {
store.next = this.first;
this.first = store;
return;
}
if (pointer.data.compareTo(item) > 0 ) {
store.next = pointer;
return;
}
if (pointer.data.compareTo(item) < 0 && pointer.next == null) {
store.next = pointer.next;
pointer.next = store;
return;
} else {
Node save = this.first;
this.first = this.first.next;
insertHelper(this.first, item);
if (pointer.data.compareTo(item) > 0) {
save.next = store;
this.first = save;
} else {
save.next = pointer;
this.first = save;
}
}
}
I'm only giving you part of the answer at first. Consider this a clue. Then there are more clues. See if you can figure it out before you get to the bottom where a whole answer is.
clue 1
This part of the code can't be in the recursive method because it makes reference to the head of the linked list. Your recursion is moving down the list, breaking it into the head and the rest, deciding whether to insert at the head and recursing if the insertion has to be in the rest.
if (pointer == null) {
store.next = this.first;
this.first = store;
return;
}
This should be modified a bit so it can go in the insert() method, which deals with the whole list.
Why?
Because this code deals with the whole list and asks the question, "Is this list empty?"
clue 2
Now, for this part of the code:
if (pointer.data.compareTo(item) > 0 ) {
store.next = pointer;
return;
}
Notice how it has a reference to the whole list. That's a bad thing.
Its asking the question, "Is the new item (to be inserted) supposed to go in front of the current head item?"
If the answer is yes, it needs to insert it in front of the current head, leave the current head with the current rest of the linked list attached as before and return something that lets the calling code attach a newly arranged rest of the list.
if (pointer.data.compareTo(item) > 0 ) {
store.next = pointer; // new item goes in front of this part of list
return store;
}
clue 3
Now, let's skip to this part of the code:
Node save = this.first;
this.first = this.first.next;
insertHelper(this.first, item);
if (pointer.data.compareTo(item) > 0) {
save.next = store;
this.first = save;
} else {
save.next = pointer;
this.first = save;
}
This code asks no questions. It just recurses since we know that no change is needed related to the head of the current linked list. When we recurse, we pass it the rest of the linked list and tell it to fix that up. We don't care how because we trust it to fix up the rest of the list by inserting the new item in the right place.
So here is what we do:
Node rest = insertHelper(pointer.next, item);
pointer.next = rest;
return pointer;
clue 4
This part of the code is the last part to consider:
if (pointer.data.compareTo(item) < 0 && pointer.next == null) {
store.next = pointer.next;
pointer.next = store;
return;
}
Now, think about why you are comparing it again. The previous code tested whether the item needed to go in front of the rest of the linked list. The answer was no.
That means there are only two possible situations left.
Either there is nothing left in the list ... and we have to put the new item on the end.
Or there is something in the list ... and clue 3 deals with that by recursing.
So this part gets a little simpler:
if (pointer.next == null) {
return store;
}
All we have to do is return the new node which will be the new "rest of the list", instead of there being nothing in the rest of the list.
One more note
Remember that the method signature has to change to be like this:
/**
* Insert the 'item' into the linked list beginning with the supplied node, 'pointer'
* #returns the new, modified linked list, with the new item in it.
*/
public Node insertHelper(Node pointer, Comparable item) {
The whole thing
This includes the changes to the 'insert' method:
public void insert(Comparable item) {
// if there isn't anything in the list, the new item becomes the whole list
if (first == null) {
Node store = new Node(item);
store.next = null;
this.first = store;
return;
}
// Otherwise let the helper fix up the list for us to store away
this.first = insertHelper(this.first, item);
}
public Node insertHelper(Node pointer, Comparable item) {
Node store = new Node(item);
if (pointer.data.compareTo(item) > 0 ) {
store.next = pointer; // new item goes in front of this part of list
return store;
}
if (pointer.next == null) {
return store; // new item becomes this part of the list
}
// The head of this part of the list is ok, fix the rest of the list
pointer.next = insertHelper(pointer.next, item);
return pointer;
}
Further comments
There is another way to do this where you store the first node in some other class and each Node only stores a pointer to the rest of the list (as next).
Then you have a method to insert that knows when it gets called that it can't be null because you couldn't call it if it was null.
There is no test for the first one being null inside insert because of that. But it means the caller has to do something like:
Node item = new Node(data);
if (list != null) {
list.insert(item);
} else {
list = item;
}
and the insert method looks like this:
if (this.next == null || this.data > item.data) { // pseudo code for greater than
item.next = this.next;
this.next = item;
return;
}
this.next.insert(item);
And that's it.

How do I add objects into a linked list?

I have been working on a project where I must implement a java class that implements the use of doubly linked lists. I have the LinkedList class finished with all my methods. I'm just unsure how to actually add node objects into the list. Here is my code so far with test at the bottom. Any help would be appreciated. Thanks
public class LinkedList {
private Node first;
private Node current;
private Node last;
private int currentIndex;
private int numElements;
public LinkedList() {
this.first = null;
this.last = null;
this.numElements = 0;
this.current = null;
this.currentIndex = -1;
}
private class Node {
Node next;
Node previous;
Object data;
}
public boolean hasNext() {
return (current != null && current.next != null);
}
public Object next() {
if (!this.hasNext()) {
throw new IllegalStateException("No next");
}
current = current.next;
return current.data;
}
public boolean hasPrevious() {
return (current != null && current.previous != null);
}
public Object previous() {
if (!this.hasPrevious()) {
throw new IllegalStateException("No previous");
}
current = current.previous;
return current.data;
}
int nextIndex() {
int index = numElements;
if (hasNext()) {
index = this.currentIndex + 1;
}
System.out.println(index + "The current index is " + current);
return index;
}
int previousIndex() {
int index = -1;
if (hasPrevious()) {
index = this.currentIndex - 1;
}
System.out.println(index + "The current index is " + current);
return index;
}
public void set(Object o) {
if (this.current == null) {
throw new IllegalStateException("No node found, cannot set.");
}
current.data = o;
}
public int size() {
return numElements;
}
public void add(Object o) {
Node newNode = new Node();
newNode.data = o;
if (first == null) {
first = newNode;
last = newNode;
newNode.next = null;
} else if (first != null) {
if (current == null) {
newNode.previous = null;
newNode.next = first;
first.previous = newNode;
first = newNode;
} else if (current == last) {
newNode.previous = current;
newNode.next = null;
current.next = newNode;
last = newNode;
} else {
newNode.previous = current;
newNode.next = current.next;
current.next.previous = newNode;
current.next = newNode;
}
}
current = newNode;
numElements++;
currentIndex++;
}
public void remove() {
if (current != null) {
if (current == first && current == last) {
first = null;
last = null;
} else if (current == last) {
current.previous = null;
last = current.previous;
} else if (current == last) {
current.previous.next = null;
last = current.previous;
} else {
current.previous.next = current.next;
current.next.previous = current.previous;
}
current = current.next;
numElements--;
}
}
}
import java.util.Scanner;
public class LinkedListTest {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
String name;
int index;
LinkedList<Object> listOne = new LinkedList<Object>();
listOne.add(object o);
}
}
The posted class LinkedList looks functional to me.
Make sure that your test code does not confuse this class and java.util.LinkedList, which Java provides for you (It's a part of the existing Collections framework).
For clarity, I would recommend renaming your class to something like MyLinkedList
The following code works and the output is "0","2":
public class MyLinkedListTest {
public static final void main(String[] args) {
MyLinkedList list = new MyLinkedList();
System.out.println("Number of items in the list: " + list.size());
String item1 = "foo";
String item2 = "bar";
list.add(item1);
list.add(item2);
System.out.println("Number of items in the list: " + list.size());
// and so on...
}
}
I'd be surprised if your code compiled, since your class isn't actually generic. Just initialize it as LinkedList listOne = new LinkedList(); (no angle brackets).
As to actually adding elements, you just need an instance of some Object to add; anything will do (assuming your internal code works properly). Try this down at the end there:
Object objectToAdd = "Strings are Objects";
listOne.add(objectToAdd);
objectToAdd = new File("C:\\foo.bar"); // Or use any other Objects!
listOne.add(objectToAdd);
Think of numbered list and look at the relations between the elements
Say I have the list:
A
B
C
What do I have to do to the relations get the list:
A
B
NewNode
C
The new next node of B is NewNode
The new previous node of C is NewNode. So an insert function would want to know the immediate previous node or the immediate next node and then adjust the relationships.
Your LinkedList doesn't have generic types so you can't declare it as
LinkedList<Object> listOne = new LinkedList<Object>();
but rather as
LinkedList listOne = new LinkedList();
And now to add elements just use your add method
listOne.add("something");
listOne.add(1);//int will be autoboxed to Integer objects
Also if you want to add data from keyboard you can use something like
String line="";
do{
System.out.println("type what you want to add to list:");
line = keyboard.nextLine();
listOne.add(line);
}while(!line.equals("exit"));
The line
LinkedList<Object> listOne = new LinkedList<Object>();
won't compile unless you change your class declaration to
class LinkedList<T>
or alternately you can just write
LinkedList listOne = new LinkedLis();
After that you should be able to add objects to your list. However, you'll need to create an Object to add to it, listOne.add(object o); won't do--at the very least you'll have to write listOne.add(new Object()). (Your code does not instantiate an Object, there is no Object that you already have called o, and besides, object o does not mean anything in Java and would not compile.
As people have mentioned your list is not generic. However as they advise you to get rid of the parameter, you can also just add <Object> or <E> to your linked list implementation and leave your initialization of the list as it is.
So in your linked list class you should do something like:
public class LinkedList<E>
This will make sure when you're using LinkedList<Object> listOne = new LinkedList<Object>();, E will be covnerted to Object
Let's improve your test a little bit so that it becomes apparent where your problems are (if any) I commented out the call to the current() method since you have not included one. (I would leave this alone as it may confuse you.) The general idea would be to add items to the linked list and walk forward and backward through it checking the items with each step.
public class LinkedListTest {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
String name;
int index;
LinkedList listOne = new LinkedList();
//Initially we should be empty so we are positioned
// at both the beginning and end of the list
assert listOne.size() == 0 :"List should be empty";
assert listOne.hasPrevious()==false: "Should be at the beginning of the list";
assert listOne.hasNext()==false : "Should be at the end of the list";
Object firstNode = "I am the first node";
listOne.add(firstNode); //we've added something
//I left this commented out since you don't have a current() method.
// assert firstNode == listOne.current() : "Our current item should be what we just added";
assert listOne.hasPrevious()==false : "Should not have moved forward in our list yet";
assert listOne.hasNext()==true : "should have an item after our current";
assert listOne.size() == 1 : "Should only have one item in the list";
Object secondNode = "I am the second node";
listOne.add(secondNode);
assert listOne.size() == 2 : "Should only have two items in the list";
assert firstNode == listOne.next() : "1st call to next should return the 1st node";
assert listOne.hasPrevious()==true : "We should be positioned after the 1st node";
assert listOne.hasNext()==true : "We should be positioned before the 2nd node";
}
}

Categories