java 的Stream函数式编程

java 的Stream函数式编程

这两天学习了一下java的函数式编程,这也是java8的特性,尽管java8增加了lambda表达式,能够实现部分函数式编程的功能(函数式编程简单来说就是对于相同的输入,一定会产生相同的输出,与状态无关,其它知识请查阅相关资料),但是这个对于java来说,这个改动有很多妥协,当然支持的功能也有限。接下来通过介绍java的Stream库来了解java的函数式编程。

1.怎么产生Stream

流(Stream)可以看成一个存储数据的仓库,我们只关心需要什么,而不用关心怎么从仓库中得到这些东西。java很多API都能将数据转为Stream,比如我们可能需要得到某个目录下的所有文件(或者目录),那么可以使用 Stream来存储。Stream的产生更多的是通过IO流来得到的。直接调用stream()方法便可得到Stream,当然还可以直接通过调用Stream.of()实现流的构造

Stream<String> words = Stream.of("first","second","third");

Stream接口还有两个静态方法用来创建流, * generate(Supplier s) *,所以我们可以通过

Stream<double> random = Stream.generate(Math:random);

来得到随机数。

2.Stream怎么使用

Stream里面的提供了很多API来处理流,通过一层的处理最后得到自己想要的流,先上一个实例,比如我需要得到一篇英语文章中的单词的长度大于10的单词的数量,使用filter()可以过滤得到结果。

int count = words.stream().filter(s -> s.length > 10).count()

这个操作的思路明显,而且我们只需要关注想要的结果就可以了,不用再去写for循环来一个一个查找,s -> s.length > 10 就是一个简单的lambda表达式,s代表输入参数,这里就是stream里面的字符串,类型可以由编译器直接推断出来(因为words的类型为String),所有不用显示的指定, ->是lambda表达式的标记,后面是具体的内容,因为只有一句话,所以没用{}括起来。意思是输出字符串的长度是否大于10,可能会有疑问?怎么看出 是否的意思呢?看一下filter的参数类型就知道,是一个 Predicate

3.怎么得到想要的结果

我们过滤完之后还是一个流,很多情况下我们需要的是一个数字或者java的基本类型。比如前面的 count()操作,Stream里面也有不少这样的方法,我们称之为规约的操作,比如 min(),max(),reduce(),collect(),其中 reduce(),collect()的功能很强大,可以得到很多自定义的结果。如果能掌握的话,java函数式编程也就掌握大半了。这里举一个简答的例子,比如我需要求总单词列表的总的字母的数量,采用reduce()实现,(当然还有很多简便的方法)

Optional<Integer> sum = words.stream.reduce((x,y) -> (x.length+y.length))

这里的 Optional可以简单的看成一个Integer,只不过这个类型提供了对 null值时的保护措施。通过 ifPresent()方法来选择性的执行。

4.一个函数式编程具体的例子:

能够实现将一个文本的单词读取出来,并且将单词流排序输出到列表当中。

package com.seanhust.eight;
import java.io.*;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Question1 {
    public static void main(String[] args){
        Path path = FileSystems.getDefault().getPath("");
        List<String> wordsList = new ArrayList<>();
        wordsList = ReadFileToWords.readFileToWords(path);
        Stream<String> longString = wordsList.stream().sorted(Comparator.comparing(String::length,Comparator.reverseOrder()));
        List<String> strings = longString.collect(Collectors.toList());
    }
}

class ReadFileToWords{
    public static List<String> readFileToWords(Path path){
        List<String> wordsList = new ArrayList<>();
        try(Scanner scan = new Scanner(path)){
            while(scan.hasNext()) {
                String[] line = scan.nextLine().split("[^a-zA-Z]");
                for (String word : line) {
                    if(!"".equals(word.trim())) {
                        wordsList.add(word.trim());
                    }
                }
            }
        }catch (IOException e){
            e.printStackTrace();
        }
        return wordsList;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值