Reputation: 349
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;
}
}
Upvotes: 2
Views: 21922
Reputation: 2773
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
Upvotes: 2