首页 > 解决方案 > 表示来自父类或子类的 getter 方法的 Lambda

问题描述

我在下面有一些代码代表父 Pojo 和子 Pojo,以及一个简单的验证器,它从它们中提取两个代表范围的值,以验证 start < end。我希望验证器足够通用,以至于它可以在构造时接受两个字段 getter 方法,然后能够传递一个 POJO 来执行范围检查。但是,我一直无法正确输入检查。我尝试让验证器构造函数采用以下所有内容:

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"

代码:

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));
  }
}

标签: javalambda

解决方案


由于每个实例都使用验证器,因此只需提供一个特定的实例方法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


推荐阅读