如何将具有谓词接口的泛型列表转换为 Lambda 表达式?
How to convert Generic List with Predicate Interface into a Lambda Expression?
我正在学习 Java 8 函数式接口并正在尝试一些示例。
我正在尝试创建一种方法,该方法将接受通用列表作为一个参数,将字符串数据过滤器参数作为另一个参数。
下面的代码按预期工作,但是当我尝试将谓词转换为 Lambda 表达式 时,我很挣扎。
@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();
}
有什么办法,我可以将谓词转换为 Lambda,如果有办法,我可以将 if-else-if 转换为三元运算符。
像:(if 条件)?return 值:(else-if 条件):return value:null;
为什么不全部放入过滤器?试试这个
return genericList.stream().filter(item ->
(item instanceof Customer && ((Customer) item).getCustomerName().equalsIgnoreCase(dataFilter)
|| (item instanceof Employee && ((Employee) item).getEmpDept().equalsIgnoreCase(dataFilter))))
.collect(Collectors.toList());
或为此过滤器提取一个函数
public boolean isAllow(T item, String dataFilter) {
return (item instanceof Customer && ((Customer) item).getCustomerName().equalsIgnoreCase(dataFilter))
|| (item instanceof Employee && ((Employee) item).getEmpDept().equalsIgnoreCase(dataFilter)))
}
//then use it in filter
return genericList.stream().filter(item -> isAllow(item, dataFilter)
.collect(Collectors.toList());
希望对您有所帮助
泛型在这里对您帮助不大,因为 Customer
和 Employee
似乎不相互兼容。只要您想使用泛型类型 <T>
,您就必须确保此类型在所有方法作用域执行中都是一致的。您所能做的就是使用显式转换。
我将从静态 Map
开始,根据传入的 Class<?>
提取映射函数。只要您想将这些与 dataFilter
进行比较,Function<Object, String>
就会导致 String
:
static Map<Class<?>, Function<Object, String>> exctractionMap() {
Map<Class<?>, Function<Object, String>> map = new HashMap<>();
map.put(Customer.class, item -> Customer.class.cast(item).getCustomerName());
map.put(Employee.class, item -> Employee.class.cast(item).getEmpDept());
return map;
}
这张静态地图暂时搁置一会,我想你的整个流可能都被简化了。这应该一起工作:
static List<String> findSelectedData(List<?> genericList, String dataFilter) {
return genericList.stream() // Stream<Object>
.map(item -> exctractionMap() // Stream<String> using the function
.get(item.getClass()) // ... get through Class<Object>
.apply(item)) // ... applied Function<Object,String>
.filter(s-> s.equalsIgnoreCase(dataFilter)) // Stream<String> equal to dataFilter
.collect(Collectors.toList()); // List<String>
}
注意:请遵守 Java 约定并将方法命名为 filterAndFindOnlySelectedData1
。
我想,你其实想要这样的东西:
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());
}
那么,来电者可以使用
List<Employee> source = …;
List<Employee> filtered
= filter_and_find_only_selected_Data(source, Employee::getEmpDept, "value");
或
List<Customer> source = …;
List<Customer> filtered
= filter_and_find_only_selected_Data(source, Customer::getCustomerName, "Bob");
或
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");
展示真正通用方法的灵活性。
我正在学习 Java 8 函数式接口并正在尝试一些示例。 我正在尝试创建一种方法,该方法将接受通用列表作为一个参数,将字符串数据过滤器参数作为另一个参数。 下面的代码按预期工作,但是当我尝试将谓词转换为 Lambda 表达式 时,我很挣扎。
@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();
}
有什么办法,我可以将谓词转换为 Lambda,如果有办法,我可以将 if-else-if 转换为三元运算符。 像:(if 条件)?return 值:(else-if 条件):return value:null;
为什么不全部放入过滤器?试试这个
return genericList.stream().filter(item ->
(item instanceof Customer && ((Customer) item).getCustomerName().equalsIgnoreCase(dataFilter)
|| (item instanceof Employee && ((Employee) item).getEmpDept().equalsIgnoreCase(dataFilter))))
.collect(Collectors.toList());
或为此过滤器提取一个函数
public boolean isAllow(T item, String dataFilter) {
return (item instanceof Customer && ((Customer) item).getCustomerName().equalsIgnoreCase(dataFilter))
|| (item instanceof Employee && ((Employee) item).getEmpDept().equalsIgnoreCase(dataFilter)))
}
//then use it in filter
return genericList.stream().filter(item -> isAllow(item, dataFilter)
.collect(Collectors.toList());
希望对您有所帮助
泛型在这里对您帮助不大,因为 Customer
和 Employee
似乎不相互兼容。只要您想使用泛型类型 <T>
,您就必须确保此类型在所有方法作用域执行中都是一致的。您所能做的就是使用显式转换。
我将从静态 Map
开始,根据传入的 Class<?>
提取映射函数。只要您想将这些与 dataFilter
进行比较,Function<Object, String>
就会导致 String
:
static Map<Class<?>, Function<Object, String>> exctractionMap() {
Map<Class<?>, Function<Object, String>> map = new HashMap<>();
map.put(Customer.class, item -> Customer.class.cast(item).getCustomerName());
map.put(Employee.class, item -> Employee.class.cast(item).getEmpDept());
return map;
}
这张静态地图暂时搁置一会,我想你的整个流可能都被简化了。这应该一起工作:
static List<String> findSelectedData(List<?> genericList, String dataFilter) {
return genericList.stream() // Stream<Object>
.map(item -> exctractionMap() // Stream<String> using the function
.get(item.getClass()) // ... get through Class<Object>
.apply(item)) // ... applied Function<Object,String>
.filter(s-> s.equalsIgnoreCase(dataFilter)) // Stream<String> equal to dataFilter
.collect(Collectors.toList()); // List<String>
}
注意:请遵守 Java 约定并将方法命名为 filterAndFindOnlySelectedData1
。
我想,你其实想要这样的东西:
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());
}
那么,来电者可以使用
List<Employee> source = …;
List<Employee> filtered
= filter_and_find_only_selected_Data(source, Employee::getEmpDept, "value");
或
List<Customer> source = …;
List<Customer> filtered
= filter_and_find_only_selected_Data(source, Customer::getCustomerName, "Bob");
或
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");
展示真正通用方法的灵活性。