更改方法参考的类型

时间:2019-04-15 08:50:16

标签: java lambda java-8 java-stream

我的代码:

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

我有3个班级,一个是BlogPostBlogPostTypeMain

我正在使用Map<BlogPostType, List<BlogPost>> Blist制作groupingBy()的地图,它工作得很好。我在 BlogPost :: getType 中使用了方法引用,也可以在(x) -> x.getType()中使用lambda表达式。

但是当我尝试更改Map的类型时,即Map<String, List<BlogPost>> Blist1,则无法使用方法参考。有什么可能的方法来使用方法引用并使类型也更改??

我在想为什么我们不能这样使用:BlogPost::getType.toString()(String)BlogPost::getType,而我们却可以在lambda (x) -> x.getType().toString()中使用它。 有什么可能的方法来使用方法引用并与类型转换相处吗?

4 个答案:

答案 0 :(得分:2)

方法引用恰好是:对某些特定方法的“引用”。

没有隐式转换或任何其他形式。只是一种具有特定签名的方法,并且通过语法快捷方式可以表达该信息而无需写下lambda表达式。

如果要使用方法引用,则该事物必须作为方法存在。换句话说,您需要像

这样的 new 方法

String getTypeAsString()

进入您的BlogPost类。只有这样,您才能通过方法引用直接调用该方法。

但是,在您的情况下,只需使用该lambda表达式,而不是显式调用toString()。在那里拥有一个与另一个方法“几乎”相同的特殊方法,只是为了让您写下一个方法引用,听起来是错误的。

或者,遵循Eran的答案中指出的有趣方法使用andThen()

最后,您的重点应该是编写对您和您的团队而言易于阅读和理解的代码。我个人的建议是在此处使用lambda,因为所有其他解决方案只会增加很多噪音,而没有实际收益。

答案 1 :(得分:2)

  

代替lambda表达式的方法引用使您的代码更加   可读,因此建议将lambda表达式替换为method   参考,尽可能

请记住将方法引用替换为单个方法调用,在您的情况下,BlogPost::getType可以正常工作,而BlogPost::getType.toString()则不能,因为它不是单个方法调用。

方法引用替换了单个方法调用,因此它不能简单地替换由 个以上方法调用 组成的lambda表达式。

答案 2 :(得分:2)

您可以使用以下两个方法引用来做到这一点,但是我会坚持使用lambda表达式,这要简单得多。

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

mapStateToProps()

答案 3 :(得分:2)

您可以使用Function.identity()来链接方法引用(任意数量)。例如,将以下函数放在groupingBy中:

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

,但最好使用lambda