我有父类(super class)对象的 ArrayList,并编写了此方法以返回其子类之一的 ArrayList。
public static ArrayList<SubClass> getSubClass(ArrayList<SuperClass> superObjects){
ArrayList<SubClass> objects = new ArrayList<>();
for (SuperClass superObject : superObjects) {
if (superObject instanceof SubClass) {
objects.add((SubClass) superObject);
}
}
return objects;
}
现在我想调用类似的方法从同一个父类(super class)对象的 ArrayList 中提取不同子类的对象。有没有办法概括此代码以将 Class 作为参数并返回该子类的对象的 ArrayList?
最佳答案
如果您传入一个类,然后调用Class.isInstance()
,则可以执行此过滤器。这称为runtime type token 。这是一个带有流和 List
接口(interface)的版本:
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
}
关于java - 将类作为参数传递给返回该类对象的 ArrayList 的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46480748/