Search code examples
javalambdastreamabstract

How to abstract method call in lambda expression?


Given the following two methods (not compilable code, just the structure):

  protected String mapABC(
    Entity entity, @Context MappingContext mappingContext) {
    return Optional.ofNullable(getSomething(entity))
      .map(
        x ->  getBlah(x::getName))
      .orElse(null);
  }

  protected String mapXYZ(
    Entity entity, @Context MappingContext mappingContext) {
    return Optional.ofNullable(getSomething(entity))
      .map(
        x ->  getBlah(x::getFirstName))
      .orElse(null);
  }

I am thinking about how it would look when the duplicate logic is avoided, so that one could write something like this structure:

protected String mapXYZ(
    Entity entity, @Context MappingContext mappingContext) {
    return xxx(getName());
  }

  protected String mapXYZ(
    Entity entity, @Context MappingContext mappingContext) {
    return xxx(getFirsName());
  }


  private String xxx(Methodreference m){
    return Optional.ofNullable(getSomething(entity))
      .map(
        x ->  getBlah(x::m))
      .orElse(null);
  }

Type of x is:

@AllArgsConstructor
@NoArgsConstructor
@Data
@Builder(toBuilder = true)
public class DetailData {
  private String name;
  private String firstname;
}

Any ideas I could try?


Solution

  • You should take a Function<DetailData, String>

    private String map(Function<DetailData, String> m){
        return Optional.ofNullable(getSomething(entity))
            .map(
                x -> getBlah(m.apply(x)))
            .orElse(null);
    }
    

    Usage:

    protected String mapXYZ(
        Entity entity, @Context MappingContext mappingContext) {
        return map(DetailData::getName);
    }
    
    protected String mapXYZ(
        Entity entity, @Context MappingContext mappingContext) {
        return map(DetailData::getFirstName);
    }