表示来自父类或子类的getter方法的Lambda

huangapple go评论70阅读模式
英文:

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&lt;Pojo, Integer&gt; //Fails on constructing vlad2 - &quot;Incompatible types in lambda expression: Expected Pojo but found ExtendedPojo&quot;.
Function&lt;? extends Pojo, Integer&gt; //Fails on getRangeStart.apply(pojo) - &quot;(capture&lt;? extends Pojo&gt;) in Function cannot be applied to Pojo&quot;
Function&lt;Object, Integer&gt; //Fails on constructing both vlad and vlad2 - &quot;Incompatible types in lambda expression: Expected Object but found ExtendedPojo&quot;

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&lt;T&gt; {
boolean isValid(T obj);
}
class MyValidator implements SomeValidatorInterface&lt;Pojo&gt; {
private Function&lt;Pojo, Integer&gt; getRangeStart;
private Function&lt;Pojo, Integer&gt; getRangeEnd;
MyValidator(Function&lt;Pojo, Integer&gt; getRangeStart, Function&lt;Pojo, Integer&gt; 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 &gt; 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&lt;Integer&gt;

MyValidator(Supplier&lt;Integer&gt; getRangeStart, Supplier&lt;Integer&gt; 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

huangapple
  • 本文由 发表于 2020年9月11日 08:07:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/63839156.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定