我已经为客户端服务器TCP数据连接创建了这个简单的压缩类,这对我来说没有构建错误,但是我得到一个运行时错误,我无法纠正。我得到的错误是线程“main”中的异常java.lang.StringIndexOutOfBoundsException:字符串索引超出范围:-1。
代码:
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);
}
}
错误:
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)
我已经尝试根据length()更改计算字符串的方式,但它没有减少错误。
谁能看到我做错了什么?
答案 0 :(得分:1)
如果str
为length 0
(空字符串)或length 1
,该怎么办?在这种情况下,str = str.substring(length -2,length-1);
将导致异常。
您需要在执行子字符串之前进行长度检查:
if(length > 1){
str = str.substring(length-2,length-1);
}
由于您只想获得一个角色,我认为您可以这样做:
if(length > 1){
str = String.valueOf(str.charAt(length-2))
}
请确保str
不为空,否则也会进行空处理。
答案 1 :(得分:1)
这种情况正在发生,因为您将空字符串传递给 punctuationChar 。
哦,因为你刚刚使用str中的最后一个字符,将它转换为字符可能更容易。
试试这个:
private boolean punctuationChar(String str) {
if (str.length() > 0) {
char lastChar = str.charAt(lastChar.length() - 1);
// Returns true if the character is anything other than a letter, digit or space
return !(Character.isLetterOrDigit(lastChar)) || Character.isWhitespace(lastChar);
}
else {
return false;
}
}
}
我在这里使用isLetterOrDigit,然后反转结果。因此,对于包含除A-Z,a-z或0-9之外的任何字符串的任何字符串,此方法将返回true。我也把空间看作不是标点符号。
如果Oracle考虑将“isPunctuation”方法放入!
,这将更容易Java中的Character类非常适合这样的检查,绝对值得一看下次你做类似的事情。 http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Character.html
答案 2 :(得分:0)
您可以更轻松地进行标点符号检查:
private boolean punctuationChar(String str) {
if (str != null && str.length() > 0) {
char c = str.charAt(str.length()-1);
return c == '.' || c =='?'||c==',' || c =='!';
} else {
return false;
}
}
通常,尽量避免字符串操作,因为它们很慢。如果您需要使用子字符串或字符串索引,请始终确保为空字符串,空字符串或短字符串做好准备