Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I make this java pluck() method more safe?

I wrote this utility function:

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;
}

I copied the idea from underscore.js. The use case is:

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);

My problem is that if the caller gets the type wrong, no exception is thrown until the caller tried to get an object from the list. Ideally, I'd like to throw a ClassCastException from the pluck method itself. However, I don't see a way to access the type of the list on run time.

Is there some trick I can use to make sure the caller doesn't end up with an invalid list?


Edit: So using the feedback I got, a safe implementation would be:

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;
}

But actually lambdaj seems to do what I wanted, so I guess I'll use that. Thanks mike!

Disclaimer: LambdaJ ( @GoogleCode | @GitHub ) - This project is not maintained anymore since the release of JDK8 (JSR 335, JEP 126).

like image 570
itsadok Avatar asked Jan 26 '12 14:01

itsadok


1 Answers

You can change your signature to as follows:

public static <T, F> List<F> pluck(String fieldName, Class<F> fieldType, 
                                           List<T> list, Class<T> listType)

The you have the list type and field type.

like image 127
Bhesh Gurung Avatar answered Sep 21 '22 13:09

Bhesh Gurung