i am currently building a linked list from scratch and everything seems to be going okay except on my test driver when i try and get an index of a certain object it gives me a value that seems to be 2 values off, (should be 3, its 5)
Test Driver
public static void main ( )
{ List<String> friends = new LinkedList <String> ();
System.out.println (" Testing problem 1");
friends.add ("joe");
friends.add ("mary");
friends.add ("jim");
friends.add ("joe"); // Lists may contain duplicate elements
friends.add (2, "sally"); // Insert at position 2
System.out.println (friends.get(3)); // Should be jim
friends.remove (0);
System.out.println (friends.indexOf ("joe")); // Should be 3
String sal = new String ("sa" + "lly");
if (! friends.contains(sal)) // "sally"
System.err.println ("Not correct");
My indexOf method
/**
*
* @returns index value, -1 if object was not found
*/
public int indexOf(Object obj) {
int index = 0;
Node<E> current = head.next;
while (current != null) {
if (current.equals( obj)) {
return index;
}
index++;
current = current.next;
}
if(index == size && obj == null){
return -1;
}
else{
return index;
}
}
My add(E value) method
public void add(E value){
Node<E> temp = new Node<E>(value,tail,tail.previous);
tail.previous = temp;
temp.previous.next = temp;
size++;
}
My add(int index, E value) method
public void add(int index, E value) {
setRef(index);
Node<E> temp = new Node<E>(value,ref,ref.previous);
temp.previous.next = temp;
ref.previous = temp;
size++;
}
any idea why i may be getting an index of 5 when it should be 3?
For those who want full source
LinkedList.java
package list;
public class LinkedList<E> implements List<E>
{
//size of list
int size = 0;
Node<E> head;
Node<E> tail;
Node<E>ref;
public LinkedList(){
head = new Node<E>(null,null,null);
tail = new Node<E>(null,null,head);
head.next = tail;
}
public void add(E value){
Node<E> temp = new Node<E>(value,tail,tail.previous);
tail.previous = temp;
temp.previous.next = temp;
size++;
}
public E get(int index){
setRef(index);
return ref.value;
}
public E set(int index, E value){
setRef(index);
E result = ref.value;
ref.value = value;
return result;
}
public void add(int index, E value) {
setRef(index);
Node<E> temp = new Node<E>(value,ref,ref.previous);
temp.previous.next = temp;
ref.previous = temp;
size++;
}
public int size(){
return size;
}
public E remove(int index){
setRef(index);
E result = ref.next.value;
ref.previous.next = ref.next;
ref.next.previous = ref.previous;
size --;
return result;
}
public void clear(){
size = 0;
head.next = tail;
tail.previous = head;
ref = null;
}
/**
* @returns true if size of list is equal to 0
*/
public boolean isEmpty(){
if(size == 0 ){
return true;
}
else{
return false;
}
}
private void setRef(int index){
ref = head.next;
for(int i = 0; i < index; i++){
ref = ref.next;
}
}
/**
*
* @returns index value, -1 if object was not found
*/
public int indexOf(Object obj) {
int index = 0;
Node<E> current = head.next;
while (current != null) {
if (current.equals( obj)) {
return index;
}
index++;
current = current.next;
}
if(index == size && obj == null){
return -1;
}
else{
return index;
}
}
/**
* @returns true if list contains Object obj
*/
public boolean contains(Object obj){
boolean isTrue;
if(!(this.indexOf(obj) == -1)){
isTrue = true;
}
else{
isTrue = false;
}
return isTrue;
}
public String toString() {
String result = "[";
Node<E> current = head;
while(current.next != null){
current = current.next;
result += current.value + ", ";
}
return result += "]";
}
public RefIterator<E> Riterator(){
return new RefIterator<E>(this);
}
public ArrayIterator<E>iterator(){
return new ArrayIterator<E>(this);
}
public ListIterator<E> listIterator(){
return new RefListIterator<E>(this);
}
public ListIterator<E> listIterator(int start){
return new RefListIterator<E>(this,start);
}
}
List.java
public interface List<E>
{
/**
* @return the size of this list
*/
int size(); // all methods in interfaces must be public
/**
* Clear this list
*/
void clear();
/**
*@return the value at a given position by index
*/
E get(int index); // index must be in bounds -- check for that later
/**
* @returns the value that is being replaced
*/
E set(int index, E value);
/**
* Insert a given value at the position index
*/
void add(int index, E value);
/**
* Inserts a given value at the end of index
*/
void add(E value);
/**
* @returns true if List is empty
*/
boolean isEmpty();
/**
* removes value at the given index
* @return value being removed
*/
E remove(int index);
int indexOf(Object obj);
boolean contains(Object obj);
String toString();
/**
* @return refrence to the iterator
*/
ArrayIterator<E>iterator();
RefIterator<E> Riterator();
ListIterator<E> listIterator();
ListIterator<E> listIterator(int start);
}
Test Driver
package list;
import list.*;
/**
* Lab 3
* Test methods added to the List interface
*
* @author (sdb)
* @version (Sep 2015)
*/
public class DriverLab01PM
{
/**
* This main method tests the List classes
* for lab 1, Data Structures and Algorithms
*/
public static void main ( )
{ List<String> friends = new LinkedList <String> ();
System.out.println (" Testing problem 1");
friends.add ("joe");
friends.add ("mary");
friends.add ("jim");
friends.add ("joe"); // Lists may contain duplicate elements
friends.add (2, "sally"); // Insert at position 2
System.out.println (friends.get(3)); // Should be jim
friends.remove (0);
System.out.println (friends.indexOf ("joe")); // Should be 3
String sal = new String ("sa" + "lly");
if (! friends.contains(sal)) // "sally"
System.err.println ("Not correct");
//////////// Uncomment the following when ready for problem 2
System.out.println ("\n\n Testing problem 2");
System.out.println (friends); // [mary, sally, jim joe]
List <String> enemies = null;
System.out.println (enemies);
enemies = new ArrayList<String> ();
System.out.println (enemies);
enemies.add ("mike");
enemies.add ("mick");
System.out.println (enemies);
if (! enemies.contains ("mike"))
System.err.println ("Not correct");
if (enemies.contains ("Mike"))
System.err.println ("Not correct");
// //////////// Uncomment the following when ready for problem 3
System.out.println ("\n\n Testing problem 3");
WordList wordList = new WordList();
List <String> words = wordList.getWordList();
System.out.println (words.indexOf ("jack")); // Should be 51595
if (!words.contains ("zoo"))
System.err.println ("Error in contains");
if (words.contains ("foobar"))
System.err.println ("Error in contains");
wordList = new WordList();
List <String> moreWords = wordList.getWordList();
if (!words.equals (moreWords))
System.err.println ("Error in equals");
if (!moreWords.equals (words))
System.err.println ("Error in equals");
moreWords.add (0, "foobar");
if (words.equals (moreWords))
System.err.println ("Error in equals");
if (moreWords.equals (words))
System.err.println ("Error in equals");
moreWords.remove(0);
moreWords.add ("foobar");
if (words.equals (moreWords))
System.err.println ("Error in equals");
if (moreWords.equals (words))
System.err.println ("Error in equals");
String foobar = new String ("foo" + "bar");
words.add (foobar); // "foobar"
if (!words.equals (moreWords))
System.err.println ("Error in equals");
if (!moreWords.equals (words))
System.err.println ("Error in equals");
System.out.println ("Testing complete");
}
}
Node class
package list;
public class Node<E>
{
E value;
Node<E> next;
Node<E> previous;
Node(E tempValue, Node<E> tempNext, Node<E> tempPrev){
this.value = tempValue;
this.next = tempNext;
this.previous = tempPrev;
}
}
Without checking the logic of your other code, your indexOf method should look like this:
public int indexOf(Object obj) {
int index = 0;
Node<E> current = head;
while (current != null) {
if (current.equals(obj)) {
return index;
}
index++;
current = current.next;
}
return -1;
}
Basically, if you haven't returned a value from the body of the for
loop, then you can deduce that the list does not contain the target value, and correctly return -1
. This is how you need to override your equals
method
public class Node<E> {
//...
public boolean equals(Object o){
return value.equals(o);
}
//...
}
This works, because <E>
is functionally the same as <E extends Object>
. And if your calling equals
of an integer type or whatever type your specifying (which is a subclass of object) at run-time it will call the equals
method residing in the Integer
class, or the closest overridden version of equals
when walking up the inheritance chain, not the Object
method
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.