Java 8 - The method map is not applicable for the arguments (<noType>)

旧巷老猫 提交于 2020-05-24 05:47:52

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!