samedi 16 mai 2020

Java reflection inside stream's filter

I have an Java POJO:

public class Event {
    private String id;
    private String name;
    private Long time;
}

A simple filtering method I created is:

public static List<Event> simpleFilter(List<Event> eventList, String value) {
    return eventList.stream().filter(Event -> Event.getName().equals(value)).collect(Collectors.toList());
}

Now my task is to create a generic method instead of simpleFilter which can be applicable for any Java POJO object and any of its field. For example, if in future there is new Java object Employee and we want to filter on its String field employeeDepartment, we can use same generic filter method by passing the List of Java object (List, Class type (Employee.class), which field (getEmployeeDepartment) and what value ("Computer") we want to filter on.

I created a method definition:

public static <T> List<T> genericStringFilterOnList(List<T> list, Class<T> c, String methodName, String value) {
}

Caller looks like:

//events is List<Event>
//getName is the method in Event on which I want to filter
//e2 is value which I want to filter
genericStringFilterOnList(events, Event.class, "getName", "e2")

My implementation is:

public static <T> List<T> genericStringFilterOnList(List<T> list, Class<T> c, String methodName, String value) {
    return list.stream().filter(m -> {
        try {
            return c.getMethod(methodName, null).invoke(c).equals(value);
        } catch (IllegalAccessException e) {
        } catch (IllegalArgumentException e) {
        } catch (InvocationTargetException e) {
        } catch (NoSuchMethodException e) {
        } catch (SecurityException e) {
        }
        return false;
    }).collect(Collectors.toList());
}

All these catch were generated by IDE because of checked exception. This doesn't seem to working as it is returning back an empty list. What I am trying to do here is - Using the class type (which is Event.class), I am getting method name using reflection and then invoking that method and then invoke which is basically calling getName() method of Event class and then equals. I also tried this -

return c.getMethod(methodName, null).invoke(c.newInstance()).equals(value);

But with this I am getting NPE on this }).collect(Collectors.toList());

Can you guys please help me in creating a generic method which can called for a List of any POJO and a filter can be applied on any of their String type methods?





Aucun commentaire:

Enregistrer un commentaire