Search code examples
java-8predicate

How to convert Generic List with Predicate Interface into a Lambda Expression?


I am learning Java 8 Functional Interface and was trying out some examples. I am trying to create a method which will accept Generic List as one argument and a String data filter argument as another. Below code is working as expected, but when I am trying to convert Predicate into Lambda Expression, then I am struggling.

@SuppressWarnings("unchecked")
public static <T> List<T> filter_and_find_only_selected_Data1(List<T> genericList, String dataFilter){
    Stream<List<T>> list = genericList.stream().map(eachListObj-> {
            if(eachListObj instanceof Employee){
                return genericList.stream().filter((Predicate<? super T>) new Predicate<Employee>() {
                    public boolean test(Employee eachEmpObj) {
                        return eachEmpObj.getEmpDept().equalsIgnoreCase(dataFilter);
                    }
                }).collect(Collectors.toList());
            }else if(eachListObj instanceof Customer){
                return genericList.stream().filter((Predicate<? super T>) new Predicate<Customer>(){
                    public boolean test(Customer eachCust) {
                        return !eachCust.getCustomerName().equalsIgnoreCase(dataFilter);
                    }
                }).collect(Collectors.toList());
            }
            return null;
    });
    return list.findAny().get();
}

Is there any way, I can convert the Predicate into Lambda as well as if there a way, I can convert if-else-if into Ternary Operator. Like: (if condition)?return Value:(else-if condition):return value:null;


Solution

  • I think, you actually want something like this:

    public static <T> List<T> filter_and_find_only_selected_Data(
        List<T> list, Function<? super T, String> stringProperty, String filterValue) {
    
        return list.stream()
            .filter(t -> filterValue.equalsIgnoreCase(stringProperty.apply(t)))
            .collect(Collectors.toList());
    }
    

    Then, the caller can use

    List<Employee> source = …;
    List<Employee> filtered
        = filter_and_find_only_selected_Data(source, Employee::getEmpDept, "value");
    

    or

    List<Customer> source = …;
    List<Customer> filtered
        = filter_and_find_only_selected_Data(source, Customer::getCustomerName, "Bob");
    

    or

    List<File> source = Arrays.asList(new File("foo", "bar"), new File("foo", "test"),
        new File("xyz"), new File("TEST"), new File("abc", "bar"), new File("bla", "Test"));
    List<File> filtered = filter_and_find_only_selected_Data(source, File::getName, "test");
    

    to demonstrate the flexibility of a truly generic method.