簡體   English   中英

編程新手 - ***更新***實踐問題拋出 StringIndexOutOfBoundsException

[英]New to programming - ***Updated*** PracticeProblem throwing StringIndexOutOfBoundsException

我正在嘗試自學 Java,最近我一直在用內置編譯器做在線練習題。 除了字符串長度小於 2 的兩個條件外,我的代碼在大多數情況下都運行良好。

這個特定練習題的 URL 是: http : //codingbat.com/prob/p123384

問題:給定一個字符串,返回一個新字符串,其中第一個和最后一個字符已交換。

例子

frontBack("code") should be→ "eodc"
frontBack("a") should be→ "a"
frontBack("ab") should be→ "ba"

這是我的代碼:

    public String frontBack(String str) {

  char firstChar = str.charAt (0);

  char lastChar = str.charAt (str.length()-1);

  String middle = str.substring(1, str.length()-1);

    if (str.length()>=3){

  return lastChar + middle + firstChar;

  }

 else {

return new StringBuilder(str).reverse().toString();

}

}

這是錯誤的兩個條件

frontBack("a") should be→ "a"

"Exception:java.lang.StringIndexOutOfBoundsException: String index out of range: -1 (line number:4)"


frontBack("") should be→ ""

"Exception:java.lang.StringIndexOutOfBoundsException: String index out of range: 0           (line number:2)"

這是解決方案,有效的代碼

public String frontBack(String str) {
  if (str.length() <= 1) return str;

  String mid = str.substring(1, str.length()-1);

  // last + mid + first
  return str.charAt(str.length()-1) + mid + str.charAt(0);
}

我的代碼和解決方案有什么區別?

任何幫助都會很棒。 我對此感到困惑,因為我的 else 語句只是返回原始字符串。 為什么任何變量(frontChar、middle、lastChar)會影響我返回的原始字符串? 提前致謝!

首先我要感謝所有幫助過我的人!*

我重新編寫了我的代碼並將其縮小到一個簡單的區別。 區別在於放置顯式語句以說明等於或小於 1 的字符串。 這顯然不能通過 catch-all else 語句隱式處理。 仍然不確定為什么? 這是相同的代碼,只有一個細微的區別; 顯式與隱式

此代碼有效...如果字符串長度小於或等於 1,則顯式返回 str。

public String frontBack(String str) {

  // This line below is the only difference 

  if (str.length() <= 1) {
   return str;
  }

  char firstChar = str.charAt (0);

  char lastChar = str.charAt (str.length()-1);

  String middle = str.substring(1, str.length()-1);


  if (str.length()>=2){

  return lastChar + middle + firstChar;

  }

  else {
  return str;
  }
}

此代碼不起作用...如果字符串長度小於或等於 1,則使用 else 語句隱式返回 str。

public String frontBack(String str) {

  char firstChar = str.charAt (0);

  char lastChar = str.charAt (str.length()-1);

  String middle = str.substring(1, str.length()-1);


  if (str.length()>=2){

  return lastChar + middle + firstChar;

  }

  else {
  return str;
  }
}

你需要編程來防御


1.

對於一個字符串

  String middle = str.substring(1, str.length()-1);

這將是

str.substring(1, 0)

這是無效的


2.

對於空字符串( length = 0 ),您的代碼將嘗試查看index = -1無效,甚至 index = 0 無效


3.

如果strnull怎么辦

你總是要考慮邊界條件:

str 為空? str 為空("") str 是 1 個字符? 還請記住,Java 的子字符串在開始位置包含但在結尾不包含。

    public String frontBack(String str) {
      if (str == null || str.length()<2){
          //if str is null - return empty. else return the string itself
          return str == null ? "" : str;
      }else{
         //do the actual first last swap
         return  str.charAt(str.length()-1)+ str.substring(1,str.length()-1) + str.charAt(0);
      } 
    }

我重新編寫了我的代碼並將其縮小到一個簡單的區別。 區別在於放置顯式語句以說明等於或小於 1 的字符串。 這顯然不能通過 catch-all else 語句隱式處理。 仍然不確定為什么?

它與隱式或顯式無關。 問題只是在方法中執行行的順序,即從上到下。

當它在“隱式”情況下到達您的 if/else 時,上面的三行,例如char firstChar = str.charAt(0); 已經發生(或已經失敗)。 對於空字符串,它將立即在該行上出現 StringIndexOutOfBounds 異常(查看異常的行號),然后該方法將停止執行,因為它將異常拋出該方法。 (對此的技術術語是abrupt completion 。)如果拋出該異常,則下面的 if/else 將不會發生,因此它無法在事后追溯防止異常。 如果您將三個使用字符串的語句從方法頂部移動到 if/else 的“if”分支內部,則該代碼將正常工作,以便在不需要時不會執行它們。

在“顯式”情況下,您添加了if (str.length() <= 1) return str; 在方法的頂部,它可以阻止下面的行執行,因為return語句將在嘗試使用字符串中不存在的字符之前退出方法。 如果它在方法中較低,那么該聲明將無濟於事。


我只想添加一些關於“null”的內容,因為此頁面上的其他回答者抱怨您的代碼無法抵御 null 參數。 考慮一下您的方法將如何處理特殊輸入是很好的,但是在這里,您的代碼已經正確地防御了 null 參數,因為當您嘗試在 null 上調用charAtlengthsubstring時,它將拋出NullPointerException方法,因為它應該。

有時應該檢查並允許空值,但在這里不應該。 如果在沒有有效字符串的情況下調用, frontBack可能返回什么? 有些人可能會說它應該返回 null,有些人可能會說它應該返回空字符串,有些人可能會說它應該將它強制轉換為一個字符串,從而返回"luln" 沒有完全合理或明確正確的方法來處理它,適用於所有調用者。 因此, frontBack應該采取 null 不是可接受的輸入的立場。 那么如果他們傳入null,那是調用者的錯,如果調用者傳入垃圾,那么他們應該把垃圾扔回他們是正確的(當然,這是比喻;你實際上會拋出一個異常對象,而不是原始輸入) 所以他們被迫妥善處理。 通過顯式將垃圾強制為有效輸入來容忍和為壞調用者找借口是錯誤的做法,因為它隱藏了錯誤並使程序的行為更加微妙。

如果該方法有副作用,例如修改數據結構、寫入文件或調用具有副作用的其他方法,則 null 輸入可能是危險的,因為該方法可能會在不使用str情況下完成一些副作用。 然后,嘗試使用str會在某個時候拋出異常,使事情未完成並處於無效狀態。 理想情況下,應該觀察到副作用完全發生或根本不發生。 在這種情況下,最好檢查 null 並在方法頂部自己拋出異常:

if (str == null) throw new NullPointerException();

這不會對這個簡單的方法產生影響,因為它沒有副作用(它純粹是函數式的)並且因為它已經無條件地調用了str方法,這將導致無論如何拋出相同的異常。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM