Johniya Blog
首页 博客 社区 问答 开发者 约米云盘 注册
从stream-api的map理解函数式编程
默凌 2024-07-11 12:12:32 北京 java 开发

通过java8 stream-api的map方法理解函数式编程思想。

例如:现在有一个字符串数组

String[] strings = new String[]{"1", "2", "3"};

现在要把数组中的字符串转为Integer类型,返回一个Integer的数组。

使用stream-api的map方法实现就是:

Integer[] res = Arrays.stream(strings).map(Integer::parseInt)
                .toArray(Integer[]::new);

这个map的完整形式是这样的:

class Anonymous implements Function<String, Integer> {

    @Override
    public Integer apply(String s) {
        return Integer.parseInt(s);
    }
}

Anonymous anonymous = new Anonymous();
Integer[] res = Arrays.stream(strings).map(anonymous)
		.toArray(Integer[]::new);

map接收一个Function类型的对象,并在内部调用该接口的apply方法

所以我们需要实现其提供的Function接口的apply方法。并把实例传给map方法。

在面向对象编程环境中,方法的参数一定是一个对象。在这个思想的影响下,我们会潜意识的认为一个对象最重要的就是对象内的状态数据(成员变量),一般实际应用中,将对象作为参数传给一个方法,目的是操作他的内部数据。

而在面向函数编程中,参数不一定是对象,也可以是一个无状态的函数。

上面的代码使用匿名内部类简化后就是:

Integer[] res = Arrays.stream(strings).map(new Function<String, Integer>() {
	@Override
	public Integer apply(String s) {
		return Integer.parseInt(s);
	}
}).toArray(Integer[]::new);

如果再使用lambda表达式简化后就是:

Integer[] res = Arrays.stream(strings).map((s) -> {
	return Integer.parseInt(s);
}).toArray(Integer[]::new);

再次简化就是:(如果方法实现只有一行,返回值相同,省略return{}

Integer[] res = Arrays.stream(strings).map(s -> Integer.parseInt(s))
		.toArray(Integer[]::new);

最后在简化:(如果parseInt参数和Function参数相同,省略参数)

Integer[] res = Arrays.stream(strings).map(Integer::parseInt)
		.toArray(Integer[]::new);

代码逻辑非常清晰,书写非常舒服。例如:

Integer sum = Stream.of(strings1, strings1)
		.flatMap(Arrays::stream)
		.filter(Objects::nonNull)
		.filter(s -> !s.trim().equals(""))
		.map(Integer::parseInt)
		.sorted(Integer::compareTo)
		.limit(5)
		.peek(this::log)
		.reduce(0, Integer::sum);
云服务器 免费试用 一键搭建个人网站 现在购买,领取免费顶级域名 糯米云
5
1
0
21
评论 0
@Johniya.top