Java 8 — Сопоставление методов неприменимо для аргументов ()

#java #eclipse #java-8 #java-stream

#java #eclipse #java-8 #java-stream

Вопрос:

Я хотел реорганизовать свой метод, который фильтрует объект AssetLink, получить объект содержимого, который является целью AssetLink, а затем установить поля объекта contentlink metadata на основе объекта Content. Мой новый метод выглядит так:

 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;
}
  

Но я получаю сообщение об ошибке .map, в котором говорится: «Сопоставление методов в типе Stream неприменимо для аргументов (NoType linkAsAssetLink ), и я этого не понимаю. Почему в нем говорится, что linkAsAssetLink имеет значение «NoType», на самом деле это AssetLink, и я могу использовать его метод в методе ContentProvider. Можете ли вы сказать мне, где я делаю ошибку?

Ответ №1:

Похоже, вы неправильно используете его. Попробуйте один из следующих способов

 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;
}
  

Или вы также можете использовать foreach:

 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;
}
  

Карта всегда должна что-то возвращать. Оператор Return может быть неявным, но он должен быть там.

Комментарии:

1. это правда, но ошибка не объясняет, что instread сообщает linkAsAssetLink о том, что он NoType, что создает путаницу.

Ответ №2:

Если вы используете круглые скобки в сопоставлении операций, вам следует использовать оператор return . Ваш код должен выглядеть примерно так

 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());
  

}

или используйте этот код

     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;
}