Let's say I have this class.
class People { private String name; private int age; /** other stuff constructor / getters / setters / etc. **/ } And let's say I have this list :
List<People> people = Arrays.asList(new People("Mark", 21), new People("Bob",17), new People("Alex", 22)); Now I want to be able to get a List for all users of a particular attribute.
Using Java 8, I can create a method that accepts the function I want like :
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; } Then I will able to perform some calls like :
List<String> listNames = processElements(people, p -> p.getName()); List<Integer> listAges = processElements(people, p -> p.getAge()); However this is not possible in Java 7 (I know that it exists in Guava, but I would come up with a solution only using the JDK).
This is with what I come up using reflection :
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; } Now I can do something like List<Object> listNames = processElements(people, "name"); which works quite well.
But I don't feel comfortable with it :
- I'm getting a
List<Object> - Whenever I use reflection, I always feel like it exists a better implementation not using it
- Using
field.setAccessible(true);is not very secure
So my questions are :
- Is it possible to do the same thing without using reflection with the JDK (not using Guava or Functional Java) ?
- How can I get a List of String or Integer according to the type of the field I pass as parameter to my method ?
Thanks
Map<String, Object>map suits your needs?List<String> result = new ArrayList<>(); for (People p : list) { result.add(p.getName()); }. What's the problem with this obvious solution? And if Guava does it, why wouldn't you be able to do it?