英文:
Lambda representing a getter method from either a parent class or a child class
问题
import java.util.function.Function;
class Pojo {
private Integer rangeOneStart;
private Integer rangeOneEnd;
public Pojo(Integer rangeOneStart, Integer rangeOneEnd) {
this.rangeOneStart = rangeOneStart;
this.rangeOneEnd = rangeOneEnd;
}
public Integer getRangeOneStart() {
return rangeOneStart;
}
public Integer getRangeOneEnd() {
return rangeOneEnd;
}
}
class ExtendedPojo extends Pojo {
private Integer rangeTwoStart;
private Integer rangeTwoEnd;
public ExtendedPojo(Integer rangeOneStart, Integer rangeOneEnd, Integer rangeTwoStart, Integer rangeTwoEnd) {
super(rangeOneStart, rangeOneEnd);
this.rangeTwoStart = rangeTwoStart;
this.rangeTwoEnd = rangeTwoEnd;
}
public Integer getRangeTwoStart() {
return rangeTwoStart;
}
public Integer getRangeTwoEnd() {
return rangeTwoEnd;
}
}
interface SomeValidatorInterface<T> {
boolean isValid(T obj);
}
class MyValidator implements SomeValidatorInterface<Pojo> {
private Function<Pojo, Integer> getRangeStart;
private Function<Pojo, Integer> getRangeEnd;
MyValidator(Function<Pojo, Integer> getRangeStart, Function<Pojo, Integer> getRangeEnd) {
this.getRangeStart = getRangeStart;
this.getRangeEnd = getRangeEnd;
}
@Override
public boolean isValid(Pojo pojo) {
Integer start = getRangeStart.apply(pojo);
Integer end = getRangeEnd.apply(pojo);
return end > start;
}
}
class Main {
public static void main(String args[]) {
ExtendedPojo pojo = new ExtendedPojo(1, 2, 3, 4);
MyValidator vlad = new MyValidator(Pojo::getRangeOneStart, Pojo::getRangeOneEnd);
System.out.println(vlad.isValid(pojo));
MyValidator vlad2 = new MyValidator(ExtendedPojo::getRangeTwoStart, ExtendedPojo::getRangeTwoEnd);
System.out.println(vlad2.isValid(pojo));
}
}
英文:
I have some code below representing a parent and child Pojo, and a simple validator that pulls two values off them representing ranges, to verify that start < end. I want to validator to be generic enough that it can accept two field getter methods at construction time, and then be able to be passed a POJO to perform the range check on. However, I have been unable to get this to type check properly. I have tried having the validator constructor taking all of the following:
Function<Pojo, Integer> //Fails on constructing vlad2 - "Incompatible types in lambda expression: Expected Pojo but found ExtendedPojo".
Function<? extends Pojo, Integer> //Fails on getRangeStart.apply(pojo) - "(capture<? extends Pojo>) in Function cannot be applied to Pojo"
Function<Object, Integer> //Fails on constructing both vlad and vlad2 - "Incompatible types in lambda expression: Expected Object but found ExtendedPojo"
Code:
import java.util.function.Function;
class Pojo {
private Integer rangeOneStart;
private Integer rangeOneEnd;
public Pojo(Integer rangeOneStart, Integer rangeOneEnd) {
this.rangeOneStart = rangeOneStart;
this.rangeOneEnd = rangeOneEnd;
}
public Integer getRangeOneStart() {
return rangeOneStart;
}
public Integer getRangeOneEnd() {
return rangeOneEnd;
}
}
class ExtendedPojo extends Pojo {
private Integer rangeTwoStart;
private Integer rangeTwoEnd;
public ExtendedPojo(Integer rangeOneStart, Integer rangeOneEnd, Integer rangeTwoStart, Integer rangeTwoEnd) {
super(rangeOneStart, rangeOneEnd);
this.rangeTwoStart = rangeTwoStart;
this.rangeTwoEnd = rangeTwoEnd;
}
public Integer getRangeTwoStart() {
return rangeTwoStart;
}
public Integer getRangeTwoEnd() {
return rangeTwoEnd;
}
}
interface SomeValidatorInterface<T> {
boolean isValid(T obj);
}
class MyValidator implements SomeValidatorInterface<Pojo> {
private Function<Pojo, Integer> getRangeStart;
private Function<Pojo, Integer> getRangeEnd;
MyValidator(Function<Pojo, Integer> getRangeStart, Function<Pojo, Integer> getRangeEnd) {
this.getRangeStart = getRangeStart;
this.getRangeEnd = getRangeEnd;
}
@Override
public boolean isValid(Pojo pojo) {
Integer start = getRangeStart.apply(pojo);
Integer end = getRangeEnd.apply(pojo);
return end > start;
}
}
class Main {
public static void main(String args[]) {
ExtendedPojo pojo = new ExtendedPojo(1,2,3,4);
MyValidator vlad = new MyValidator(Pojo::getRangeOneStart, Pojo::getRangeOneEnd);
System.out.println(vlad.isValid(pojo));
MyValidator vlad2 = new MyValidator(ExtendedPojo::getRangeTwoStart, ExtendedPojo::getRangeTwoEnd);
System.out.println(vlad2.isValid(pojo));
}
}
答案1
得分: 1
由于验证器是针对每个实例使用的,只需提供一个特定的实例方法作为Supplier<Integer>
MyValidator(Supplier<Integer> getRangeStart, Supplier<Integer> getRangeEnd) {
this.getRangeStart = getRangeStart;
this.getRangeEnd = getRangeEnd;
}
// ...
ExtendedPojo pojo = new ExtendedPojo(1, 2, 3, 4);
MyValidator vlad = new MyValidator(pojo::getRangeOneStart, pojo::getRangeOneEnd);
如果您不想使用这种特定的构造方式,您需要将范围获取器移到共同的接口,或者至少移到Pojo
类中,并在ExtendedPojo
中覆盖它。
英文:
Since the validator is being used per instance just provide a specific instance method as Supplier<Integer>
MyValidator(Supplier<Integer> getRangeStart, Supplier<Integer> getRangeEnd) {
this.getRangeStart = getRangeStart;
this.getRangeEnd = getRangeEnd;
}
// ...
ExtendedPojo pojo = new ExtendedPojo(1,2,3,4);
MyValidator vlad = new MyValidator(pojo::getRangeOneStart, pojo::getRangeOneEnd);
If you don't want to use such specific construction you need to move the range getter to the common interface or at least the Pojo
class and override this in ExtendedPojo
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论