[英]Predicates java 8 with generics and inheritance
我有三個Foo Boo Goo對象,它們具有Foo超類的Boo和Goo子類型。
我正在使用謂詞來過濾列表,如下所示
public class Predicates {
public static Predicate<Foo> isBoo() {
foo -> {
Boo boo = (Boo) foo;
return boo.isBoo();
};
}
public static Predicate<Goo> isGoo() {
foo -> {
Goo goo = (Goo) foo;
return goo.isGoo();
};
}
}
接下來要實現的是具有通用類型,而不是指定編譯時類型。
public class Predicates {
public static <T extends Foo> Predicate<T> isBoo() {
foo -> {
// check both with instanceof
};
}
public static <T extends Foo> Predicate<T> isGoo() {
foo -> {
Goo goo = (Goo) foo;
return boo.isGoo();
};
}
public static <T extends Foo> Predicate<T> isFoo() {
isGoo().or(isBoo());
}
}
當注釋器使用OR或AND將多個謂詞組合在一起時,似乎無法將泛型與謂詞一起使用。 知道謂詞可能具有不同的類型,但是仍然擴展了超類。
需要光!
為什么不為每個子類型定義多個謂詞,然后將這些謂詞添加到列表中,最后通過對列表中的所有謂詞進行or
來構造謂詞。
public static Predicate<Foo> anotherIsFoo() {
return predicates.stream()
.reduce(foo -> false, (a, b) -> a.or(b));
}
上面的代碼假定predicates
是包含每個子類型的所有謂詞的列表。
完整的代碼如下所示:
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
class Foo {}
class Boo extends Foo {}
class Goo extends Foo {}
public class Predicates {
public static List<Predicate<Foo>> predicates = List.of(isGoo(), isFoo());
public static Predicate<Foo> isGoo() {
return foo -> foo instanceof Goo;
}
public static Predicate<Foo> isBoo() {
return goo -> goo instanceof Boo;
}
public static Predicate<Foo> anotherIsFoo() {
return predicates.stream()
.reduce(foo -> false, (a, b) -> a.or(b));
}
public static Predicate<Foo> isFoo() {
return foo -> foo instanceof Foo;
}
public static void main(String[] args) {
List<Foo> list = List.of(new Boo(), new Goo(), new Goo(), new Goo());
List<Boo> boos = list.stream()
.filter(Predicates.isBoo())
.map(boo -> (Boo) boo)
.collect(Collectors.toList());
System.out.println(boos.size()); // 1
List<Goo> goos = list.stream()
.filter(Predicates.isGoo())
.map(goo -> (Goo) goo)
.collect(Collectors.toList());
System.out.println(goos.size()); //3
List<Foo> foos = list.stream()
.filter(Predicates.isFoo())
.collect(Collectors.toList());
System.out.println(foos.size()); // 4
List<Foo> foos1 = list.stream()
.filter(Predicates.anotherIsFoo())
.collect(Collectors.toList());
System.out.println(foos1.size()); // 4
}
}
上面的代碼回答了您的查詢-“即使在同一列表中,我也不能繼承兩種不同的類型!”
上面的代碼需要Java 9或更高版本。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.