如果您傳入課程,則可以執行此過濾器,然後致電Class.isInstance()
。這叫做runtime type token。這是流的版本和List
接口:
public <T> List<T> filterList(List<? super T> list, Class<T> subClass) {
return list.stream().
filter(o -> subClass.isInstance(o)).
map(o -> (T) o).
collect(Collectors.toList());
}
如果你真的想用一個ArrayList
,那麼你需要手動篩選:
public <T> ArrayList<T> filterList(List<? super T> list, Class<T> subClass) {
ArrayList<T> result = new ArrayList<>();
for (Object obj : list) {
if (subClass.isInstance(obj)) {
result.add((T) obj);
}
}
return result;
}
您可以測試它像這樣:
List<Number> nums = new ArrayList<>();
nums.add(1);
nums.add(2);
nums.add(3L);
nums.add(4L);
nums.add(5.0F);
nums.add(6.0F);
nums.add(7.0);
nums.add(8.0);
List<Integer> ints = filterList(nums, Integer.class);
// prints [1, 2]
System.out.println(Arrays.toString(ints.toArray()));
運行時類型令牌是一種常見的泛型慣用語。例如。 EnumMap使用它太:
private static enum Foo {One, Two, Three}
Map<Foo, Integer> map = new EnumMap(Foo.class);
更新
按照意見從@Valentin Ruano,這是一個簡潔,無警告的基於流的過濾器:
public <T> ArrayList<T> filterList(List<? super T> list, Class<T> subClass) {
return list.stream().
return list.stream().
filter(o -> subClass.isInstance(o)).
map(o -> subClass.cast(o)). // warning-free casting
collect(Collectors.toCollection(ArrayList::new)); // forcing an ArrayList collector
}
你可以通過在類的子類型和使用,但我覺得你可能沒有正確使用泛型。如果你需要一個'SubClass'列表,然後創建一個並使用它。如果你只需要一個取決於'SuperClass'行爲的列表,那就用它來代替。 –