Изменить тип ссылки на метод - PullRequest
2 голосов
/ 15 апреля 2019

Мой код:

class BlogPost {
    String title;
    String author;
    BlogPostType type;
    int likes;

    public BlogPost(String title, String author, BlogPostType type, int likes) {
        this.title = title;
        this.author = author;
        this.type = type;
        this.likes = likes;
    }
//getter setter
}

и:

public enum BlogPostType {
    NEWS,
    REVIEW,
    GUIDE
}

и:

public static void main(String[] args) {
        List<BlogPost> posts = Arrays.asList(new BlogPost("Start Java", "Ram", BlogPostType.NEWS, 11),
            new BlogPost("Start Java 8", "Rajou", BlogPostType.REVIEW, 101),
            new BlogPost("Functional programming", "Das", BlogPostType.REVIEW, 111),
            new BlogPost("Lambda", "Ramos", BlogPostType.GUIDE, 541));

        Map<BlogPostType, List<BlogPost>> Blist = posts.stream().collect(groupingBy(BlogPost::getType));
        System.out.println(Blist);
}}

У меня есть три класса, один это BlogPost, BlogPostTypeи Main.

Я делаю карту Map<BlogPostType, List<BlogPost>> Blist, используя groupingBy(), и она прекрасно работает.я использовал ссылку на метод там BlogPost :: getType , я также могу использовать лямбда-выражение (x) -> x.getType().

Но когда я пытаюсь изменить тип карты, то есть Map<String, List<BlogPost>> Blist1, я не могу использовать Ссылка на метод .Есть ли какой-нибудь возможный способ использовать ссылку на метод и получить также измененный тип ??

Я думаю, почему мы не можем использовать так: BlogPost::getType.toString() или (String)BlogPost::getType, в то время как мы можем сделать это в лямбда (x) -> x.getType().toString(),Любые возможные способы использовать ссылку на метод и ладить с преобразованием типа также?

Ответы [ 4 ]

2 голосов
/ 15 апреля 2019

вы можете использовать Function.identity() для цепочки ссылок на метод (сколько хотите). Например, поместите следующую функцию в groupingBy:

Function.<BlogPost>identity()
        .andThen(BlogPost::getType)
        .andThen(BlogPostType::toString)

но лучше использовать лямбду

2 голосов
/ 15 апреля 2019

Ссылка на метод вместо лямбда-выражения делает ваш код более читабельным, поэтому рекомендуется заменить лямбда-выражение ссылкой на метод, По возможности .

Помнитессылка на метод заменяет одиночный вызов метода, в вашем случае BlogPost::getType будет работать нормально, в то время как BlogPost::getType.toString() не будет работать, поскольку это не одиночный вызов метода.

Ссылка на метод заменяет aвызов одного метода, поэтому он не может просто заменить лямбда-выражение, состоящее из более чем одного вызова метода .

2 голосов
/ 15 апреля 2019

Вы можете сделать это с двумя ссылками на методы следующим образом, но я бы придерживался лямбда-выражения, которое намного проще.

Map<String, List<BlogPost>> Blist = 
    posts.stream()
         .collect(Collectors.groupingBy(((Function<BlogPost,BlogPostType>)BlogPost::getType).andThen(BlogPostType::toString)));

или

Function<BlogPost,BlogPostType> getType = BlogPost::getType;
Map<String, List<BlogPost>> Blist = 
    posts.stream()
         .collect(Collectors.groupingBy(getType.andThen(BlogPostType::toString)));
2 голосов
/ 15 апреля 2019

Ссылка на метод просто , что: «ссылка» на какой-то конкретный метод.

Нет неявного преобразования или чего-либо еще. Просто метод, который имеет определенную подпись и синтаксический ярлык , чтобы выразить это без записи лямбда-выражения.

Если вы хотите использовать ссылку на метод, эта вещь должна существовать как метод. Другими словами, вам потребуется новый метод, такой как

String getTypeAsString()

в ваш BlogPost класс. Только тогда вы можете перейти и напрямую вызвать этот метод через ссылку на метод.

Но в вашем случае просто используйте вместо этого лямбда-выражение, которое явно вызывает toString(). Звучит неправильно, что там есть специальный метод, который "почти" работает так же, как и другой метод, просто чтобы вы могли записать ссылку на метод.

В качестве альтернативы, следуйте интересному подходу, указанному в ответе Эрана, использовать andThen().

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

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