问题
I wanted to refactor my method which filter AssetLink object, get Content object that is a target of AssetLink, and then set fields of ContentLinkMetadata object basing on Content object. My new method looks like that:
private List<ContentLinkMetadata> getAndFillInternalLinks(final Lesson lesson) {
List<ContentLinkMetadata> internalLinks = new ArrayList<>();
lesson.getAssetLinks().stream()
.filter(linkAsAssetLink -> ALLOWED_INTERNAL_LINK_TYPES.contains(linkAsAssetLink.getTargetType()))
.map(linkAsAssetLink -> {
Content link = contentProvider.getLazyById(linkAsAssetLink.getTargetId());
ContentLinkMetadata internalLink = new ContentLinkMetadata();
internalLink.setDescription(link.getDescription());
internalLink.setId(link.getId());
internalLink.setTitle(link.getTitle());
internalLink.setFriendlyUrl(friendlyUrlResolver.makeUrl(link));
internalLink.setTypeId(link.getTypeId());
internalLinks.add(internalLink);
});
return internalLinks;
}
But I'm getting error on .map which says "The method map in type Stream is not applicable for the arguments (noType linkAsAssetLink) and i don't understand that. Why it says that linkAsAssetLink is "noType" it is AssetLink in fact and I can use it's method in contentProvider's method. Can you tell me where am I doing a mistake?
回答1:
Looks like you are ussing it wrong. Try one of the following ways
private List<ContentLinkMetadata> getAndFillInternalLinks(final Lesson lesson) {
List<ContentLinkMetadata> internalLinks = lesson.getAssetLinks().stream()
.filter(linkAsAssetLink -> ALLOWED_INTERNAL_LINK_TYPES.contains(linkAsAssetLink.getTargetType()))
.map(linkAsAssetLink -> {
Content link = contentProvider.getLazyById(linkAsAssetLink.getTargetId());
ContentLinkMetadata internalLink = new ContentLinkMetadata();
internalLink.setDescription(link.getDescription());
internalLink.setId(link.getId());
internalLink.setTitle(link.getTitle());
internalLink.setFriendlyUrl(friendlyUrlResolver.makeUrl(link));
internalLink.setTypeId(link.getTypeId());
return internalLink;
}).collect(Collectors.toList());
return internalLinks;
}
Or you can use foreach as well:
private List<ContentLinkMetadata> getAndFillInternalLinks(final Lesson lesson) {
List<ContentLinkMetadata> internalLinks = new ArrayList<>();
lesson.getAssetLinks().stream()
.filter(linkAsAssetLink -> ALLOWED_INTERNAL_LINK_TYPES.contains(linkAsAssetLink.getTargetType()))
.map(linkAsAssetLink -> {
Content link = contentProvider.getLazyById(linkAsAssetLink.getTargetId());
ContentLinkMetadata internalLink = new ContentLinkMetadata();
internalLink.setDescription(link.getDescription());
internalLink.setId(link.getId());
internalLink.setTitle(link.getTitle());
internalLink.setFriendlyUrl(friendlyUrlResolver.makeUrl(link));
internalLink.setTypeId(link.getTypeId());
return internalLink;
}).foreach(internalLinks::add);
return internalLinks;
}
Map always should return something. Return statement can be implicit, but it should be there.
回答2:
If you use parentheses in the operation map you should use return operator. Your code should look something like this
private List<ContentLinkMetadata> getAndFillInternalLinks(final Lesson lesson) {
List<ContentLinkMetadata> internalLinks = lesson.getAssetLinks().stream()
.filter(linkAsAssetLink -> ALLOWED_INTERNAL_LINK_TYPES.contains(linkAsAssetLink.getTargetType()))
.map(linkAsAssetLink -> {
Content link = contentProvider.getLazyById(linkAsAssetLink.getTargetId());
ContentLinkMetadata internalLink = new ContentLinkMetadata();
internalLink.setDescription(link.getDescription());
internalLink.setId(link.getId());
internalLink.setTitle(link.getTitle());
internalLink.setFriendlyUrl(friendlyUrlResolver.makeUrl(link));
internalLink.setTypeId(link.getTypeId());
return internalLink;
}).collect(Collectors.toList());
}
or use this code
List<ContentLinkMetadata> internalLinks = lesson.getAssetLinks().stream()
.filter(linkAsAssetLink -> ALLOWED_INTERNAL_LINK_TYPES.contains(linkAsAssetLink.getTargetType()))
.map(linkAsAssetLink -> linkAsAssetLink.getTargetId())
.filter(Objects::nonNull)
.map(function)
}).collect(Collectors.toList())
private Function<Object, ContentLinkMetadata> function = this::toInternalLink;
private ContentLinkMetadata toInternalLink(Object linkAsAssetLink){
Content link = contentProvider.getLazyById(linkAsAssetLink.getTargetId());
ContentLinkMetadata internalLink = new ContentLinkMetadata();
internalLink.setDescription(link.getDescription());
internalLink.setId(link.getId());
internalLink.setTitle(link.getTitle());
internalLink.setFriendlyUrl(friendlyUrlResolver.makeUrl(link));
internalLink.setTypeId(link.getTypeId());
return internalLink;
}
来源:https://stackoverflow.com/questions/39806441/java-8-the-method-map-is-not-applicable-for-the-arguments-notype