Reputation: 8487
When develop java code, always need extract some property from a list of some object, e.g.
List<Foo> fooList = ...
List<Integer> idList = new ArrayList<>();
for(Foo f : fooList){
idList.add(f.getId());
}
because in production environment we used java7
, so I cannot use java8
stream to implement this. So I write an util code to implement this
public static <T, O> List<T> extract(Collection<O> collection, String propertyName) {
List<T> result = new ArrayList<>(collection.size());
for (O o : collection) {
Object val = getFieldValue(propertyName, o);
result.add((T) val);
}
return result;
}
then I implement this just like below
List<Integer> idList = extract(fooList,"id");
but it's not friendly to refactor, if I changed the property name,e.g. id --> fooId, it cannot perceive to this change.
So I want to know how to implement this function refactor friendly and also use it easily?
Upvotes: 0
Views: 509
Reputation: 11619
I think you can have a look to Guava. Guava has a Function interface and
Collections2.transform(Collection<E>, Function<E,E2>)
method provides the feature you require. Following is an example:
final Collection<Foo> fooList = ...;
final Collection<Integer> idList =
Collections2.transform(fooList, new Function<Foo, Integer>(){
@Override
public Integer apply(final Foo foo){
return foo.getId();
}
});
Upvotes: 1
Reputation: 44995
Even if you don't use Java 8, you can apply the same logic by using a function as next:
public interface Function<T, R> {
/**
* Applies this function to the given argument.
*
* @param t the function argument
* @return the function result
*/
R apply(T t);
}
public static <T, O> List<T> extract(Collection<O> collection, Function<O, T> mapper) {
List<T> result = new ArrayList<>(collection.size());
for (O o : collection) {
result.add(mapper.apply(o));
}
return result;
}
Indeed using a function instead of a String literal
is much easier to refactor and much more Object Oriented.
Your method call will then be something like that:
List<Integer> idList = extract(fooList, new Function<Foo, Integer>() {
@Override
public Integer apply(final Foo f) {
return f.getId();
}
});
Upvotes: 3