假设我有这门课。
class People {
private String name;
private int age;
/** other stuff constructor / getters / setters / etc. **/
}
让我说我有这个清单:
List<People> people = Arrays.asList(new People("Mark", 21), new People("Bob",17), new People("Alex", 22));
现在我希望能够为特定属性的所有用户获得List
。
使用Java 8,我可以创建一个接受我想要的函数的方法:
public static <X, Y> List<Y> processElements(Iterable<X> source, Function <X, Y> mapper) {
List<Y> l = new ArrayList<>();
for (X p : source)
l.add(mapper.apply(p));
return l;
}
然后我将能够执行一些调用:
List<String> listNames = processElements(people, p -> p.getName());
List<Integer> listAges = processElements(people, p -> p.getAge());
然而,在Java 7中这是不可能的(我知道它存在于Guava中,但我只想使用JDK来提出解决方案)。
这与我使用反射的方式有关:
public static List<Object> processElements(List<People> l, String fieldName) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException{
Field field = People.class.getDeclaredField(fieldName);
field.setAccessible(true);
List<Object> list = new ArrayList<>();
for(People p : l){
list.add(field.get(p));
}
field.setAccessible(false);
return list;
}
现在我可以做List<Object> listNames = processElements(people, "name");
之类的工作。
但我觉得不舒服:
List<Object>
field.setAccessible(true);
不是很安全所以我的问题是:
由于
答案 0 :(得分:6)
您可以使用Java 7的匿名类完成与Java 8完全相同的操作
public static <X, Y> List<Y> processElements(Iterable<X> source, Function <X, Y> mapper) {
List<Y> l = new ArrayList<>();
for (X p : source)
l.add(mapper.apply(p));
return l;
}
List<String> listNames = processElements(people, new Function<People, String>() {
public String apply(People person) {
return person.getName();
}
});
答案 1 :(得分:2)
在Java 8中,您可以按如下方式执行此操作:
List<String> names = people.stream()
.map(Person::getName).collect(Collectors.asList());
您的Java 8解决方案也适用于Java 7,因为它不使用任何特殊语言构造,而只使用Java 8中引入的接口Function
。如果您需要这样的接口,您可以简单地声明它你自己!
public interface Function<T, R> {
R apply(T t);
}