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