簡體   English   中英

使用Predicate實現過濾器 <T> 在Java8中

[英]Implementing a filter with Predicate<T> in Java8

為了掌握Java8,我試圖實現一個簡單的Repo來存儲不同對象的列表。

我的出發點是:

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

所以我能夠插入列表並檢索列表。

我的下一步是實現一個通用的過濾方法:

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

結果

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

如何實現通用的查找方法?

我不得不承認,我不確定,設計與

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

是個不錯的選擇。 也許有更好的解決方案。

首先,您應該使您的方法通用,這將讓編譯器決定您傳遞哪個Predicate ,並相應地推斷出特定類型。 此外, result.stream().filter(predicate)將為您提供Stream而不是List 您需要在List收集流。

此外,由於您已經有了get(Class<T>)方法,因此可以使用它而不是在find()方法中執行repo.get(c) find()方法。 你也可以在這里使用java.util.Optional類:

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

您需要修復方法簽名。 通用通配符類型本質上是獨立的 - Java編譯器沒有理由相信它? 類型與另一種類型有什么關系? 類型。

嘗試:

public <T> List<T> get(Class<T> c)

public <T> void put(Class<T> c, List<T> list)

public <T> List<T> find(Class<T> c, Predicate<T> predicate)

這個可配置的<T>參數允許調用者指定他們想要的任何類型,但也讓編譯器知道“嘿,這個List<T>Predicate<T> ?那是相同的T ,所以你可以完全做過濾”

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM