Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing a filter with Predicate<T> in Java8

Tags:

java

java-8

To get the grips on to Java8, I am trying to implement a simple Repo for storing Lists of different Objects.

My startingpoint is this:

public class MyRepo {

    Map<Class, List<?>> repo =new HashMap<>();

    public List<?> get(Class c){
        List<?> result= repo.get(c);
        return (result==null)?new ArrayList<>():(List<?>) result;
    }

    public void put(Class c,List<?> l){
        repo.put(c, l);
    }
}    

So I am able to insert Lists and retrieve lists.

My next step would be to implement a generic filter-method:

public List<?> find(Class c, Predicate<?> predicate){
    List<?> result= repo.get(c);
    return (result==null)?new ArrayList<>():(List<?>)result.stream().filter(predicate);
}

which results in

java: incompatible types: java.util.function.Predicate<capture#1 of ?> cannot be converted to java.util.function.Predicate<? super capture#2 of ?>

How to implement a generic find-method?

I have to admit, that I am not sure, that the design with

Map<Class, List<?>> repo =new HashMap<>();

is a good choice. Maybe there is a better solution.

like image 556
Thomas Junk Avatar asked Aug 23 '26 17:08

Thomas Junk


1 Answers

First you should make your methods generic, that will let compiler decide which Predicate you are passing, and infer a particular type accordingly. Also, result.stream().filter(predicate) will give you a Stream and not a List. You need to collect the stream in a List.

Moreover, since you already have the get(Class<T>) method, you can use that instead of doing repo.get(c) method in find() method. And you can also use java.util.Optional class here:

Map<Class, List<?>> repo =new HashMap<>();

public <T> List<T> get(Class<T> c){
    return Optional.ofNullable((List<T>)repo.get(c)).orElse(new ArrayList<>());
}

public <T> void put(Class<T> c,List<T> l){
    repo.put(c, l);
}

public <T> List<T> find(Class<T> c, Predicate<T> predicate){
    return get(c).stream().filter(predicate).collect(Collectors.toList());
}
like image 101
Rohit Jain Avatar answered Aug 25 '26 06:08

Rohit Jain