在静态方法中使用Javasupplier/Function传递方法
Using Java supplier/Function to pass method in static method
我有几个 类:
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
}
如您所见,这两个 类 的验证部分是相同的。我想尝试使它成为一种通用方法。为此:
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;
}
}
然后用 :
调用它
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);
}
但我收到一条错误消息 Non static method cannot be referenced from static context.
编辑:
我尝试的另一个选项是使用 Function
,即我传入 <TextContent, String> mapper
并在我的流中使用 .map(x -> mapper.apply(x)
。但是,当我尝试将它传递给函数 validateInputs(textAsset, requestId, TextContent::externalId)
时,我得到了同样的错误 Non static method cannot be referenced from static context.
我建议让这两种类型实现相同的接口:
public interface Content {
public String getExternalId();
public static String externalId(Content content) {
return content == null ? null : content.getExternalId();
}
}
然后将 validateInput
签名更改为:
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
}
如果你还想在这里提取一个常用的方法,你可以这样写:
public static <E> void commonValidate(List<E> assets, String requestId, Function<E, String> mapper) {
Set<String> uniqueIds = assets.stream().map(mapper).collect(Collectors.toSet());
}
在泛型的帮助下完成:
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;
}
}
然后调用它:
validateInput(imageAssets, requestId, ImageContent::externalImageId);
我有几个 类:
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
}
如您所见,这两个 类 的验证部分是相同的。我想尝试使它成为一种通用方法。为此:
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;
}
}
然后用 :
调用它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);
}
但我收到一条错误消息 Non static method cannot be referenced from static context.
编辑:
我尝试的另一个选项是使用 Function
,即我传入 <TextContent, String> mapper
并在我的流中使用 .map(x -> mapper.apply(x)
。但是,当我尝试将它传递给函数 validateInputs(textAsset, requestId, TextContent::externalId)
时,我得到了同样的错误 Non static method cannot be referenced from static context.
我建议让这两种类型实现相同的接口:
public interface Content {
public String getExternalId();
public static String externalId(Content content) {
return content == null ? null : content.getExternalId();
}
}
然后将 validateInput
签名更改为:
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
}
如果你还想在这里提取一个常用的方法,你可以这样写:
public static <E> void commonValidate(List<E> assets, String requestId, Function<E, String> mapper) {
Set<String> uniqueIds = assets.stream().map(mapper).collect(Collectors.toSet());
}
在泛型的帮助下完成:
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;
}
}
然后调用它:
validateInput(imageAssets, requestId, ImageContent::externalImageId);