2016-12-23 36 views
-5

我有一個ArrayList,其中包含Staff類的實例。當我寫了下面的代碼,我用的IntelliJ告知「for聲明不循環」:爲什麼在循環ArrayList時產生一個警告,「for語句不循環」在IntelliJ中

public String getTypist() { 
    String tempTy = ""; 
    for (Staff g : staffList) { 
     if (g.getStaffID().contains("TY") && g.isAvailable()){ 
      tempTy = g.getStaffID(); 
     } 
     staffList.remove(g); 
     staffWorking.add(g); 
     break; 
    } 

    return tempTy; 
} 

我,因爲我認爲這是正確使用for環路上ArrayList的方式真的很困惑。我的for循環是怎麼回事?

+4

你叫'打破;'第一次迭代過程中,因此該循環永遠不會重複。另外,在迭代它時,你不能修改'ArrayList'。 – nickb

+1

如果你想循環播放列表,你爲什麼要放棄? –

+0

只要刪除break語句。 – Mordechai

回答

1

for環路含有break聲明,始終執行不管在循環之前發生的,所以第一個循環發生後,break發生,沒有別的是繼循環。這基本上使得它好像根本沒有for循環,因爲一次執行代碼是執行一系列語句的默認方式。糾正這個問題包括確保break只執行一些循環(具體來說,確保它只在你想成爲最後一個循環的循環上執行)。製作該修正增加了一些其他修補程序,你會得到類似的代碼這一點:

public String getTypist() { 
    for (Staff s : staffList) { 
     if (s.getStaffID().contains("TY") && s.isAvailable()){ 
      staffList.remove(s); 
      staffWorking.add(s); 
      return s.getStaffID(); 
     } 
    } 

    return ""; 
} 

但是,還存在另一種解決辦法,讓你避免在ArrayList在所有迭代。您可以使用此代碼替換代碼,因爲它使用ArrayList本身的方法來完成任務,將沒有任何for循環工作:

public String getTypist() { 
    ArrayList<Staff> staffWorking = new ArrayList<>(staffList);   
    staffWorking.removeIf(staff -> !(staff.isAvailable() && staff.getStaffID().contains("TY"))); 

    staffList.removeAll(staffWorking); 

    Optional<Staff> typist = staffWorking.stream().findFirst(); 
    if(typist.isPresent()){ 
     return typist.getStaffID(); 
    }else{ 
     return ""; 
    } 
} 

雖然甚至可以簡化和完善,這(這代碼支持併發過濾等多處理器系統中,會快很多):

private static final Predicate<Staff> isATypistWorker = 
    staff -> staff.isAvailable() && staff.getStaffID().contains("TY"); 

public String getTypist() { 
    ArrayList<Staff> typistWorkers = staffList.stream() 
     .parallel() 
     .filter(isATypistWorker) 
     .distinct() 
     .collect(Collectors.toCollection(ArrayList::new)); 

    staffList.removeAll(typistWorkers); 
    staffWorkers.addAll(typistWorkers); 

    Optional<Staff> typist = typistWorkers.stream().findFirst(); 

    return typist.isPresent() ? typist.getStaffID() : ""; 
} 
0

您不循環,因爲您在循環的第一次迭代後總是break。我認爲你需要用括號括住你的if聲明。

public String getTypist() { 
    String tempTy = ""; 

    for (Staff g : staffList) { 
     if (g.getStaffID().contains("TY") && g.isAvailable()) { 
      tempTy = g.getStaffID(); 
      staffList.remove(g); 
      staffWorking.add(g); 
      break; 
     } 
    } 

    return tempTy; 
} 

而且我張貼不起作用,因爲同時通過它循環,你不能從ArrayList刪除代碼。但這是一個不同的問題。

+0

我使用了休息,因爲我試圖找到滿足條件的第一個實例,然後停止...我想一個for循環不是正確的語句? – Patrick

+0

我發佈的代碼與發佈的代碼之間的區別在於我的if語句包含循環中其餘的邏輯。如果您不明白區別,請閱讀[this](http://stackoverflow.com/a/15786982/2464657)。另外一個'for'循環不適合你,因爲你不能從一個'ArrayList'中迭代它。如果你不明白,請閱讀[this](http://stackoverflow.com/questions/10431981/remove-elements-from-collection-while-iterating)。 – Adam