![](/img/trans.png)
[英]Error after compiling Java project : Exception in thread “main” java.lang.StringIndexOutOfBoundsException: String index out of range: 0
[英]Compression class error - Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -1
我為客戶端服務器 TCP 數據連接創建了這個簡單的壓縮類,對我來說一切都很好,沒有構建錯誤,但是我遇到了一個無法糾正的運行時錯誤。 我得到的錯誤是線程“main”中的異常 java.lang.StringIndexOutOfBoundsException: String index out of range: -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() 計算字符串的方式,但並沒有減少錯誤。
誰能看到我做錯了什么?
如果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
不為空,否則也要進行空處理。
發生這種情況是因為您將空字符串傳遞給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,然后反轉結果。 因此,對於末尾包含 AZ、az 或 0-9 以外的任何字符串的任何字符串,此方法將返回 true。 我也將空格計算為不是標點符號。
如果 Oracle 考慮過放入“isPunctuation”方法,這會更容易!
Java 中的 Character 類非常適合這樣的檢查,下次您做類似的事情時絕對值得一看。 http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Character.html
您可以更輕松地檢查標點符號:
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;
}
}
一般來說,盡量避免字符串操作,因為它們很慢。 如果您需要處理子字符串或字符串索引,請始終確保為空字符串、空字符串或短字符串做好准備
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.