Я написал эту служебную функцию:
public static <T> List<T> pluck(String fieldName, List list)
throws NoSuchFieldException, IllegalAccessException {
if (list.isEmpty()) {
return new ArrayList<T>();
}
Class c = list.get(0).getClass();
Field f = c.getField(fieldName);
ArrayList<T> result = Lists.newArrayList();
for (Object object : list) {
result.add((T) f.get(object));
}
return result;
}
Я скопировал идею из underscore.js . Вариант использования:
ArrayList<Person> people = new ArrayList<Person>;
people.add(new Person("Alice", "Applebee"));
people.add(new Person("Bob", "Bedmington"));
people.add(new Person("Charlie", "Chang"));
List<String> firstNames = pluck("firstName", people);
Моя проблема заключается в том, что если вызывающий объект получает неверный тип, исключение не выдается, пока вызывающий объект не попытается получить объект из списка. В идеале я бы хотел выбросить ClassCastException
из самого метода pluck
. Однако я не вижу способа получить доступ к типу списка во время выполнения.
Есть ли какая-нибудь хитрость, которую я могу использовать, чтобы убедиться, что у вызывающего абонента нет неверного списка?
Редактировать: Поэтому, используя полученные отзывы, безопасная реализация будет:
public static <T,F> List<F> pluck(String fieldName, Class<F> fieldType,
List<T> list, Class<T> listType)
throws NoSuchFieldException, IllegalAccessException {
Field f = listType.getField(fieldName);
ArrayList<F> result = new ArrayList<F>();
for (T element : list) {
result.add(fieldType.cast(f.get(element)));
}
return result;
}
Но на самом деле лямбдаж, кажется, делает то, что хотел, поэтому, думаю, я воспользуюсь этим. Спасибо, Майк!
Отказ от ответственности: LambdaJ ( @ GoogleCode | @ GitHub ) - Этот проект больше не поддерживается с момента выпуска JDK8 ( JSR 335 , JEP 126 ).