1

I have a couple of classes:

public class TextContent {
    private String externalId;
}

public class ImageContent {
    private String externalImageId;
}

public static void validateImageInput(List<ImageContent> imageAssets, String requestId) {
    if(CollectionUtils.isEmpty(imageAssets)) {
        throw some Error;
    }

    Set<String> uniqueIds = imageAssets.stream().map(ImageContent::externalImageId).collect(Collectors.toSet());
    if(uniqueIds.size() != imageAssets().size()) {
        throw some Error;
    }

    //Do some processing
}

public static void validateTextInput(List<TextContent> textAssets, String requestId) {
    if(CollectionUtils.isEmpty(textAssets)) {
        throw some Error;
    }

    Set<String> uniqueIds = textAssets.stream().map(ImageContent::externalId).collect(Collectors.toSet());
    if(uniqueIds.size() != textAssets().size()) {
        throw some Error;
    }

    //Do some processing
}

As you can see the validation part is the same for both these classes. And I wanted to try and make this a common method. For that:

public static void validateInput(List<?> assets, String requestId, Supplier<String> mapper) {
    if(CollectionUtils.isEmpty(assets)) {
        throw some error;
    }

    Set<String> uniqueIds = assets.stream().map(x -> mapper.get()).collect(Collectors.toSet());
    if(uniqueIds.size() != assets().size()) {
        throw some Error;
    }
}

and then call it with :

public static void validateAllInputs(List<ImageContent> imageAssets, List<TextContent> textAssets, String requestId) {
    validateInput(imageAssets, requestId, ImageContent::externalImageId);
    validateInput(textAssets, requestId, TextContent::externalId);
    doSomeProcessingWithText(textAssets, requestId);
    doSomeProcessingWithImage(imageAssets, requestId);
}

But I get an error saying Non static method cannot be referenced from static context.

Edit: The other option I tried was using Function , i.e I pass in a <TextContent, String> mapper and in my stream I use .map(x -> mapper.apply(x). However when I try passing it to the function validateInputs(textAsset, requestId, TextContent::externalId) I get the same error Non static method cannot be referenced from static context.

user1692342
  • 5,007
  • 11
  • 69
  • 128

2 Answers2

0

I'd suggest making both types implement the same interface:

public interface Content {
    public String getExternalId();

    public static String externalId(Content content) {
        return content == null ? null : content.getExternalId();
    }
}

Then change the validateInput signature to:

public static void validateInput(List<? extends Content> assets, String requestId) {
    if(CollectionUtils.isEmpty(assets)) {
        throw some error;
    }

    Set<String> uniqueIds = assets.stream().map(Content::externalId).collect(Collectors.toSet());
    if(uniqueIds.size() != assets.size()) {
        throw some error;
    }

    //Do some processing
}

And if you still want to extract a common method here, you can write one like this:

public static <E> void commonValidate(List<E> assets, String requestId, Function<E, String> mapper) {
    Set<String> uniqueIds = assets.stream().map(mapper).collect(Collectors.toSet());
}
Timir
  • 1,395
  • 8
  • 16
0

Done this with the help of generics:

public static <T> void validateInput(List<T> assets, String requestId, Function<T, String> mapper) {
    if(CollectionUtils.isEmpty(assets)) {
        throw some error;
    }

    Set<String> uniqueIds = assets.stream().map(mapper).collect(Collectors.toSet());
    if(uniqueIds.size() != assets().size()) {
        throw some Error;
    }
}

And then call it using:

validateInput(imageAssets, requestId, ImageContent::externalImageId);
user1692342
  • 5,007
  • 11
  • 69
  • 128