Search code examples
javastringlistbuilder

JAVA - LString Java , linked strings


In my program, I have a LString.java that isn't supposed to have an input or output but how you test the compilation is through LStringTest.java. This program runs through junit.jar as well.

My program does good for the first half but then starts giving me error messages that I am not exactly sure what it is telling me to do and how to fix it. I guess my question is how do I come about solving these errors so that my program can run through the rest of the testing without any errors. Thank you in advance!

Below, is the output of my code so far and the errors that it is giving me:

----jGRASP exec: java LStringTest
Running constructor, length, toString tests (10 tests)
Starting tests: ..........
Time: 0.010
OK! (10 tests passed.)

Running compareTo and equals tests (18 tests)
Starting tests: ..................
Time: 0.022
OK! (18 tests passed.)

Running charAt and setCharAt tests (18 tests)
Starting tests: ..................
Time: 0.032
OK! (18 tests passed.)

Running substring tests (63 tests)
Starting tests: ...............................................................
Time: 0.076
OK! (63 tests passed.)

Running replace tests (31 tests)
Starting tests: E...EEE....EEEEEEE...EEEEEEE...
Time: 0.046

There were 18 failures:
1) test61aReplaceEmptyString(LStringTest$LStringReplaceTestSpecial)
java.lang.NullPointerException
        at LString.replace(LString.java:171)
        at LStringTest$LStringReplaceTestSpecial.test61aReplaceEmptyString(LStringTest.java:553)
        ... 10 more
2) test63aReplaceOneChar(LStringTest$LStringReplaceTestSpecial)
java.lang.NullPointerException
        at LString.replace(LString.java:190)
        at LStringTest$LStringReplaceTestSpecial.test63aReplaceOneChar(LStringTest.java:576)
        ... 10 more
3) test63bReplaceOneChar(LStringTest$LStringReplaceTestSpecial)
java.lang.AssertionError: replace returned different LString expected same:<a> was not:<axyzzy>
        at org.junit.Assert.fail(Assert.java:88)
        at org.junit.Assert.failNotSame(Assert.java:737)
        at org.junit.Assert.assertSame(Assert.java:680)
        at LStringTest$LStringReplaceTestSpecial.test63bReplaceOneChar(LStringTest.java:587)
        ... 10 more
4) test63cReplaceOneChar(LStringTest$LStringReplaceTestSpecial)
org.junit.ComparisonFailure: Replace of One Character LString is wrong expected:<[]xyzzy> but was:<[a]xyzzy>
        at org.junit.Assert.assertEquals(Assert.java:115)
        at LStringTest$LStringReplaceTestSpecial.test63cReplaceOneChar(LStringTest.java:593)
        ... 10 more
5) test71aReplacePrepend[0](LStringTest$LStringReplaceTest)
java.lang.NullPointerException
        at LString.replace(LString.java:190)
        at LStringTest$LStringReplaceTest.test71aReplacePrepend(LStringTest.java:660)
        ... 10 more
6) test71bReplaceAppend[0](LStringTest$LStringReplaceTest)
java.lang.AssertionError: replace returned different LString expected same:<abcd> was not:<abcdxyzzy>
        at org.junit.Assert.fail(Assert.java:88)
        at org.junit.Assert.failNotSame(Assert.java:737)
        at org.junit.Assert.assertSame(Assert.java:680)
        at LStringTest$LStringReplaceTest.test71bReplaceAppend(LStringTest.java:673)
        ... 10 more
7) test71cReplaceInMiddle[0](LStringTest$LStringReplaceTest)
java.lang.AssertionError: replace returned different LString expected same:<abcd> was not:<abxyzzycd>
        at org.junit.Assert.fail(Assert.java:88)
        at org.junit.Assert.failNotSame(Assert.java:737)
        at org.junit.Assert.assertSame(Assert.java:680)
        at LStringTest$LStringReplaceTest.test71cReplaceInMiddle(LStringTest.java:683)
        ... 10 more
8) test71dReplaceAtStart[0](LStringTest$LStringReplaceTest)
java.lang.NullPointerException
        at LString.replace(LString.java:190)
        at LStringTest$LStringReplaceTest.test71dReplaceAtStart(LStringTest.java:690)
        ... 10 more
9) test71eReplaceAtEnd[0](LStringTest$LStringReplaceTest)
java.lang.AssertionError: replace returned different LString expected same:<abcd> was not:<abxyzzy>
        at org.junit.Assert.fail(Assert.java:88)
        at org.junit.Assert.failNotSame(Assert.java:737)
        at org.junit.Assert.assertSame(Assert.java:680)
        at LStringTest$LStringReplaceTest.test71eReplaceAtEnd(LStringTest.java:703)
        ... 10 more
10) test71fReplaceInMiddle[0](LStringTest$LStringReplaceTest)
java.lang.AssertionError: replace returned different LString expected same:<abcd> was not:<abxyzzycd>
        at org.junit.Assert.fail(Assert.java:88)
        at org.junit.Assert.failNotSame(Assert.java:737)
        at org.junit.Assert.assertSame(Assert.java:680)
        at LStringTest$LStringReplaceTest.test71fReplaceInMiddle(LStringTest.java:713)
        ... 10 more
11) test71gReplaceAll[0](LStringTest$LStringReplaceTest)
org.junit.ComparisonFailure: replace(0, length) is wrong expected:<[]xyzzy> but was:<[a]xyzzy>
        at org.junit.Assert.assertEquals(Assert.java:115)
        at LStringTest$LStringReplaceTest.test71gReplaceAll(LStringTest.java:721)
        ... 10 more
12) test71aReplacePrepend[1](LStringTest$LStringReplaceTest)
java.lang.NullPointerException
        at LString.replace(LString.java:190)
        at LStringTest$LStringReplaceTest.test71aReplacePrepend(LStringTest.java:660)
        ... 10 more
13) test71bReplaceAppend[1](LStringTest$LStringReplaceTest)
java.lang.AssertionError: replace returned different LString expected same:<Yet another even longer string.> was not:<Yet another even longer string.xyzzy>
        at org.junit.Assert.fail(Assert.java:88)
        at org.junit.Assert.failNotSame(Assert.java:737)
        at org.junit.Assert.assertSame(Assert.java:680)
        at LStringTest$LStringReplaceTest.test71bReplaceAppend(LStringTest.java:673)
        ... 10 more
14) test71cReplaceInMiddle[1](LStringTest$LStringReplaceTest)
java.lang.AssertionError: replace returned different LString expected same:<Yet another even longer string.> was not:<Yet another evexyzzyn longer string.>
        at org.junit.Assert.fail(Assert.java:88)
        at org.junit.Assert.failNotSame(Assert.java:737)
        at org.junit.Assert.assertSame(Assert.java:680)
        at LStringTest$LStringReplaceTest.test71cReplaceInMiddle(LStringTest.java:683)
        ... 10 more
15) test71dReplaceAtStart[1](LStringTest$LStringReplaceTest)
java.lang.NullPointerException
        at LString.replace(LString.java:190)
        at LStringTest$LStringReplaceTest.test71dReplaceAtStart(LStringTest.java:690)
        ... 10 more
16) test71eReplaceAtEnd[1](LStringTest$LStringReplaceTest)
java.lang.AssertionError: replace returned different LString expected same:<Yet another even longer string.> was not:<Yet another evexyzzy>
        at org.junit.Assert.fail(Assert.java:88)
        at org.junit.Assert.failNotSame(Assert.java:737)
        at org.junit.Assert.assertSame(Assert.java:680)
        at LStringTest$LStringReplaceTest.test71eReplaceAtEnd(LStringTest.java:703)
        ... 10 more
17) test71fReplaceInMiddle[1](LStringTest$LStringReplaceTest)
java.lang.AssertionError: replace returned different LString expected same:<Yet another even longer string.> was not:<Yet anotxyzzy string.>
        at org.junit.Assert.fail(Assert.java:88)
        at org.junit.Assert.failNotSame(Assert.java:737)
        at org.junit.Assert.assertSame(Assert.java:680)
        at LStringTest$LStringReplaceTest.test71fReplaceInMiddle(LStringTest.java:713)
        ... 10 more
18) test71gReplaceAll[1](LStringTest$LStringReplaceTest)
org.junit.ComparisonFailure: replace(0, length) is wrong expected:<[]xyzzy> but was:<[Y]xyzzy>
        at org.junit.Assert.assertEquals(Assert.java:115)
        at LStringTest$LStringReplaceTest.test71gReplaceAll(LStringTest.java:721)
        ... 10 more

Test Failed! (18 of 31 tests failed.)

Test failures: abandoning other phases.

 ----jGRASP wedge: exit code for process is 1.
 ----jGRASP: operation complete.

Here is my code, LString.java:

import java.io.*;
import java.util.*;

public class LString {

     node front;
     int size;

     // Creating a node class
     private class node {
          char data;
          node next;

          public node () {

          }

          public node (char newData) {
                this.data = newData;
          }

          public node (char newData, node newNext) {
                this.data = newData;
                this.next = newNext;
          }

     }

     // Constructors
     public LString(){
          this.size = 0;
          this.front = null;
     }

     public LString(String original) {
          this.size = original.length();
          if (original.length() > 0) {

              this.front = new node(original.charAt(0));
              node curr = this.front;

              for (int i =1; i <  original.length(); i++) {
                  curr.next = new node(original.charAt(i));
                  curr = curr.next;
              }
          }
     }

    // Length method, returns the length of LString
     public int length() {
        return this.size;
    }

    //  compareTo method, compares this LString to anotherLString, returns 0 if equal,
    //  -1 if lexicogrpahically less, and 1 if lexicographically greater
    public int compareTo(LString anotherLString) {
        int len1 = length();
        int len2 = anotherLString.length();
        int lim = Math.min(len1, len2);

        node cn1 = front;
        node cn2 = anotherLString.front;

        int k = 0;
        while (k  < lim) {
            char c1 = cn1.data;
            char c2 = cn2.data;
            if (c1 != c2) {
                return c1-c2;
            }
            k++;
            cn1 = cn1.next;
            cn2 = cn2.next;
        }

        return len1 - len2;
    }

    // a boolean equals method that returns true if LString and other are the same, false if not
    public boolean  equals(Object other) {
        if (this == other) {
            return true;
        }

        if (other instanceof LString) {
            LString otherLString = (LString)other;
            int n = length();
            if (n == otherLString.length()) {
                node n1 = front;
                node n2 = otherLString.front;

                while (n1 != null) {
                    if (n1.data != n2.data) {
                        return false;
                    }
                    n1 = n1.next;
                    n2 = n2.next;
                }
                return true;
            }
        }

        return false;
    }


    // charAt returns the character of LString at the argument index
    public char charAt(int index) {

        if ((index < 0) || (index >= this.length())) {
            throw new IndexOutOfBoundsException();
        }

        node curNode = front;
        for (int i = 0; i < this.length(); i++, curNode = curNode.next) {
            if (i == index) {
                return curNode.data;
            }
        }

        throw new IllegalStateException();
    }

    public void setCharAt(int index, char ch) {
      if (index < 0 || index >= this.length()) {
         throw new IndexOutOfBoundsException();
      }

      else {
         node currNode = front;
         for (int i = 0; i <this.length(); i++, currNode = currNode.next) {
            if (i == index) {
            currNode.data = ch;
            }
         }
      }
   }

    public LString substring(int start, int end) {
      if (start < 0 || end > this.length() || start > end) {
         throw new IndexOutOfBoundsException();
      }

      LString substring = new LString();
      if (start == end) {
         return substring;
      }
      node node = this.front;
      for (int i = 0; i < start; i++) {
         node = node.next;
      }

      node copy = new node(node.data);
      substring.front = copy;
      for (int i = start+1; i < end; i++) {
         node = node.next;
         copy = copy.next = new node(node.data);
      }

      substring.size = end - start;
      return substring;      
    }

    public LString replace(int start,   int end, LString lStr) {
        if (start < 0 || end > length() || start > end) {
         throw new IndexOutOfBoundsException();
    }

    LString result = new LString();
    node node = this.front;
    node copy = new node(node.data);
       result.front = copy;
    for (int i = 1; i < start; i++) {
        node = node.next;
        copy = copy.next = new node(node.data);
    }

    node replace = lStr.front;
    for (int i = 0; i < lStr.length(); i++) {
        copy = copy.next = new node(replace.data);
        replace = replace.next;
    }

    for (int i = start; i < end; i++) {
        node = node.next;
    }

    for (int i = end; i < length(); i++) {
        node = node.next;
        copy = copy.next = new node(node.data);
    }

    result.size = length() + lStr.length() - (end - start);
    return result;
}   

    public void append(char data) {

        this.size++;

        if  (front == null) {
             front = new node(data);
             return;
        }

        node curr = front;
        while (curr.next != null) {
             curr = curr.next; 
        }

        curr.next = new node(data);

    }

    public void prepend (char data) {

        front = new node(data, front);
        size++;
    }


    public void delete(int index) {

        if (index == 0) {
             front = front.next;
        } else {
             node curr = front;
             for (int i = 0; i < index - 1; i++){
                curr = curr.next;
             }

             curr.next = curr.next.next;
          }

        size--;
    }

    public String toString() {
        StringBuilder result = new StringBuilder();

        node curr = front;
        while (curr != null) {

            result.append(curr.data);
            curr = curr.next;
        }

        return result.toString();
    }

    public void add(int index, char data) {
         if (index == 0) {
              front = new node(data, front);
         }  else {
              node curr = front;
              for (int i = 0; i < index - 1;  i++){
                    curr = curr.next;
              }

              curr.next = new node(data, curr.next);
            }
         }

    public void print() {
    System.out.println(this.toString());

    }
} 

Error 1 for @ScaryWombat:

Here is the code from LStringTest.java:

@Test public void test61aReplaceEmptyString() {
         LString testLString = new LString();
         LString newLString = testLString.replace(0, 0, replaceLString);
         assertEquals("Replace of Empty LString is wrong",
               replaceString, newLString.toString());
         assertSame("replace returned different LString", testLString, newLString);
      }

This is the snippet of code from LString.java that it is giving errors. From line 171...

LString result = new LString();
    node node = this.front;
    node copy = new node(node.data);
       result.front = copy;

Solution

  • Ok lets break this up a bit

    In test61aReplaceEmptyString when you call

     LString testLString = new LString();
    

    it calls the constructor

    // Constructors
     public LString(){
          this.size = 0;
          this.front = null;
     }
    

    see that this.front is null

    Now when you call testLString.replace(0, 0, replaceLString);

    you will see that in replace there is the code

    node node = this.front;
    

    remember that this.front is null so now node is also null

    BTW very confusing that class name and object name is the same.

    Anyway, as node is null then

     new node(node.data);
    

    will throw a NPE

    To fix it you need to test if the existing LString is empty (i.e. nodes are null)

    public LString replace(int start,   int end, LString lStr) {
        if (start < 0 || end > length() || start > end) {
         throw new IndexOutOfBoundsException();
        }
    
        if (this.front == null) {
           return lStr; // maybe correct logic for you?
        }