如何按类型动态创建通用的 lambda 实现?
How to dynamically create a generic lambda implementation by type?
例如,我有 class
public class Human {
private String name;
...
}
我想实现这样的东西:
(1)
List<Human> humans = initHumans();
Equals<Human> humanEquals = new Equals<>();
Predicate<Human> filter = humanEquals.filter("name", "John");
List<Human> filteredHumans = humans
.stream()
.filter(filter)
.collect(Collectors.toList());
等于:
public class Equals<T> extends AbstractPredicate<T> {
public java.util.function.Predicate<T> filter(String fieldName, String fieldValue) {
....
}
}
是否可以实现过滤器方法来提供 (1) 行为?
我想 return 一个 Predicate
这样的:
Predicate<Human> predicate = human -> human.getName().equals("John");
同样适用于其他 classes:
Predicate<Car> filter = humanEquals.filter("color", "red");
//like this:
Predicate<Car> predicate= human -> human.getColor().equals("red");
是的,这可以通过反射来实现:
public static <T> Predicate<T> filter(Class<T> clazz, String fieldName, Object fieldValue) {
// 1
return (T instance) -> {
try {
final Field field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
return fieldValue.equals(field.get(instance));
} catch (NoSuchFieldException | IllegalAccessException e) {
// 2
}
return false;
};
}
- 我创建了一个方法
static
因为我不知道 AbstractPredicate
是什么以及为什么需要创建实用程序的实例 class.
- 我在不使用 getter 的情况下直接从字段中获取值 - 我们应该遵守什么命名约定? (可能会有所改进)
用途是:
final Predicate<Human> filter = Equals.filter(Human.class, "name", "John");
System.out.println(filter.test(new Human("John"))); // true
System.out.println(filter.test(new Human("Andrew"))); // false
还有几个问题需要我们思考——验证参数(1),处理异常(2)。
另一个选项可以使用 Function<T, E>
来提供对 getter 的引用:
public static <T, E> Predicate<T> filter(Function<T, E> supplier, E value) {
return (T instance) -> supplier.apply(instance).equals(value);
}
使用示例:
final Predicate<Human> predicate = Equals.filter(Human::getName, "John");
System.out.println(predicate.test(new Human("John"))); // true
System.out.println(predicate.test(new Human("Andrew"))); // false
例如,我有 class
public class Human {
private String name;
...
}
我想实现这样的东西:
(1)
List<Human> humans = initHumans();
Equals<Human> humanEquals = new Equals<>();
Predicate<Human> filter = humanEquals.filter("name", "John");
List<Human> filteredHumans = humans
.stream()
.filter(filter)
.collect(Collectors.toList());
等于:
public class Equals<T> extends AbstractPredicate<T> {
public java.util.function.Predicate<T> filter(String fieldName, String fieldValue) {
....
}
}
是否可以实现过滤器方法来提供 (1) 行为?
我想 return 一个 Predicate
这样的:
Predicate<Human> predicate = human -> human.getName().equals("John");
同样适用于其他 classes:
Predicate<Car> filter = humanEquals.filter("color", "red");
//like this:
Predicate<Car> predicate= human -> human.getColor().equals("red");
是的,这可以通过反射来实现:
public static <T> Predicate<T> filter(Class<T> clazz, String fieldName, Object fieldValue) {
// 1
return (T instance) -> {
try {
final Field field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
return fieldValue.equals(field.get(instance));
} catch (NoSuchFieldException | IllegalAccessException e) {
// 2
}
return false;
};
}
- 我创建了一个方法
static
因为我不知道AbstractPredicate
是什么以及为什么需要创建实用程序的实例 class. - 我在不使用 getter 的情况下直接从字段中获取值 - 我们应该遵守什么命名约定? (可能会有所改进)
用途是:
final Predicate<Human> filter = Equals.filter(Human.class, "name", "John");
System.out.println(filter.test(new Human("John"))); // true
System.out.println(filter.test(new Human("Andrew"))); // false
还有几个问题需要我们思考——验证参数(1),处理异常(2)。
另一个选项可以使用 Function<T, E>
来提供对 getter 的引用:
public static <T, E> Predicate<T> filter(Function<T, E> supplier, E value) {
return (T instance) -> supplier.apply(instance).equals(value);
}
使用示例:
final Predicate<Human> predicate = Equals.filter(Human::getName, "John");
System.out.println(predicate.test(new Human("John"))); // true
System.out.println(predicate.test(new Human("Andrew"))); // false