2016-10-25 93 views
0

我寫了一個Predicate代碼,花費下列條件Object,並測試其:謂詞泛型方法

  1. 如果Object類型爲String,包含"k"那麼它應該返回true。
  2. 如果Object類型是Integer並且大於100那麼它應該返回true。
  3. 如果Object類型是Employee這是班級,並且員工的工資大於60000,它應該返回true。

書面Predicate方法我寫的remove方法,根據Predicate方法去除列表中的值之後。

public class ConditionalRemove { 
    public static void main(String[] args) { 
     ArrayList<String> list = new ArrayList<String>(Arrays.asList("ramesh", "kushal", "suresh", "kc")); 
     System.out.println(conditionalRemove(list)); 
    } 

    public static <T> List<T> conditionalRemove(ArrayList<T> list) { 
     ConditionCheck<T> cond = new ConditionCheck<>(); 
     for (T t : list) { 
      if (cond.test(t)) { 
       list.remove(t); 
      } 
     } 
     return list; 
    } 

    static class ConditionCheck<T> implements Predicate<T> { 
     @Override 
     public boolean test(T t) { 
      if (t instanceof String) { 
       return (((String) t).contains("k")); 
      } else if (t instanceof Integer) { 
       return ((int) t > 100); 
      } else if (t instanceof Employee) { 
       return ((int) ((Employee) t).getSalary() < 60000); 
      } 
      return true; 
     } 
    } 
} 

編譯此代碼後,我發現Exception in thread "main" java.util.ConcurrentModificationException

+0

您從列表中,而你迭代它(在'conditionalRemove()'要修復刪除,使列表的副本,並重復說 – nbokmans

+0

@nbokmans - 沒必要 - 只需使用迭代明確。 –

+1

可能重複[迭代通過哈集合,避免ConcurrentModificationException當在循環中刪除](http://stackoverflow.com/questions/223918/iterating-through-a-collection-avoiding-concurrentmodificationexception-when-re) –

回答

2

的問題是,當你遍歷要更新的列表。這個問題可以通過更新代碼被固定爲

public static <T> List<T> conditionalRemove(ArrayList<T> list) { 
     ConditionCheck<T> cond = new ConditionCheck<>(); 
     Iterator it = list.iterator(); 
     while(it.hasNext())  
     { 
      it.next(); 
      if (cond.test(t)) { 
       it.remove(); 
      } 
     } 
     return list; 
    } 
+0

而不是'it.remove(t)'我寫了'it.remove()'這對我很有用。 –

+0

變量't'沒有被定義。 – saka1029

2

由於您使用的Java 8中,功能性的方法是創建一個新的過濾列表:

public static <T> List<T> conditionalRemove(ArrayList<T> list) { 
    return list.stream() 
      .filter(new ConditionCheck<>()) 
      .collect(Collectors.toList()); 
} 

你甚至可以取代靜態內部通過只是一個方法類:

public static <T> List<T> conditionalRemove(ArrayList<T> list) { 
    return list.stream() 
      .filter(ConditionalRemove::test) 
      .collect(Collectors.toList()); 
} 

private static <T> boolean test(T t) { 
    // your predicate implementation... 
} 
1

一些數據結構拋出java.util.ConcurrentModificationException當你一個迭代過程中對其進行修改,以做成功,你需要使用同步結構如「CopyOnWriteArrayList」,這是java文檔參考

希望這能幫助你!

問候。

2

不要重新發明輪子:使用Collection#removeIf()

public static <T> List<T> conditionalRemove(ArrayList<T> list) { 
    list.removeIf(new ConditionCheck<>()); 
    return list; 
} 

在一條線,這是不值得創建調用方法的努力......只是使單線電話在線: 。

public static void main(String[] args) { 
    List<String> list = new ArrayList<>(Arrays.asList("ramesh", "kushal", "suresh", "kc")); 
    list.removeIf(new ConditionCheck<>()); 
    System.out.println(list); 
}