I’ve created this simple compression class for a client server TCP data connection and it all looks fine to me with no build errors however I am getting a run time error that I cannot correct. The error I am getting is Exception in thread “main” java.lang.StringIndexOutOfBoundsException: String index out of range: -1.
Code:
import java.io.Serializable;
import java.util.ArrayList;
public class CompressedMessage implements Serializable
{ // this instance variable will store the original, compressed and decompressed message
private String message;
public CompressedMessage(String message)
{
// begin by coding this method first - initialise instance variable message with the original message
this.message = message;
}
public String getMessage()
{
return this.message;
}
private boolean punctuationChar(String str)
{
// Hint: check if the last character in the string is a punctuation
int length = str.length();
str = str.substring(length -2,length-1);
if(str.equals(",") || str.equals("!") || str.equals(".") || str.equals("?"))
{
return true;
}
else
{
return false;
}
}
private String getWord(String str)
{ // Hint: if last character in string is punctuation then remove
if(punctuationChar(str)== true)
{
//remove punctuation of last char
str = str.substring(0,str.length()-1);
}
return str;
}
public void compress()
{ /* read through section 3 of the practical 5 document
to get you started. This is called by the server,
have a look at the server code where it is called */
ArrayList<String> newMessage = new ArrayList<String>();
String[] words = message.split(" ");
for (String word : words)
{
getWord(word);
//if word has already appeared replace with position of previous word
if(newMessage.contains(word))
{
String str = Integer.toString(newMessage.indexOf(word));
str = str + " ";
newMessage.add(str);
}
else
{
word = word + "";
newMessage.add(word);
}
//if word had a punctuation at the end add it back in
//System.out.println(word);
}
this.message = newMessage.toString();
System.out.println("****************COMPRESSING*****************");
System.out.println(newMessage);
}
public void decompress()
{ /* read through section 3 of the practical 5 document
to get you started. This is called by the client,
have a look at the client code where it is called */
ArrayList<String> decompMessage = new ArrayList<String>();
String[] words = message.split(" ");
for (String word : words)
{
getWord(word);
if(word.substring(0,1).matches("[0-9]"))
{
int num = Integer.parseInt(word);
decompMessage.add(decompMessage.get(num));
}
else
{
decompMessage.add(word);
}
}
this.message = decompMessage.toString();
System.out.println("****************DECOMPRESSING*****************");
System.out.println(decompMessage);
}
}
Error:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -1
at java.lang.String.substring(String.java:1952)
at CompressedMessage.punctuationChar(CompressedMessage.java:24)
at CompressedMessage.getWord(CompressedMessage.java:40)
at CompressedMessage.compress(CompressedMessage.java:61)
at P5_Server.waitForData(P5_Server.java:72)
at P5_Server.main(P5_Server.java:159)
I have tried changing the way a calculated the strings based on the length() but it didn’t reduce the errors.
Can anyone see what I’m doing wrong?
What if you
strislength 0(empty string ) orlength 1? In that casestr = str.substring(length -2,length-1);will result into exception.You need to put a length check before performing the substring:
Since you are trying to get only one character, I think you can simply do as:
Please make sure that
stris not null otherwise put a null handling as well.