本章介绍
本章主要介绍Java中的函数式编程在本项目中的应用,非常简略。各位只需要稍加实践就可以发现函数式编程的妙用。如果想详细入门Java函数式编程的话,下面这个链接很不错。
Java 8 中的 Streams API 详解
举例说明
- 我想判断一个List中是不是所有的元素都符合某个条件,比如本项目中有一个逻辑是,判断某一个List中是不是所有的元素都是SchemeNumber类,这样才可以进行
+
的计算。
Tokens.stream().allMatch(e -> e.type() == Description.Number)
- 在某些结构的某些位置,多个类型的SchemeElement都可以放置,比如,在SchemeApply结构的第二个参数中,可以纺织一个过程,可以放置一个Atom,因为Atom可以指向一个过程。这种结构在多个地方都可以出现,比如单独的一个调用,
()
中的第一个参数可以是一个过程,如下
((lambda (x y z) (+ x y z)) 3 4 5)
或者是一个Atom
(fun 3 4 5)
既然是多次出现,就有必要把这个断言设置为一个函数,这样更为优雅,代码如下
Predicate<SchemeToken> IsAtom = e -> e.type() == Description.Atom
Predicate<SchemeToken> IsProcedure = e -> e.type() == Description.Procedure
Predicate<SchemeToken> IsAtomOrProcedure = IsAtom.or(IsProcedure)
...
Tokens.stream().allMatch(IsAtomOrProcedure);
- 承接上面的问题,当我判断某一个列表中的元素的运行时类型都是SchemeNumber那么,我想对其进行强制类型转换,并保存到一个列表中,怎么做呢?
Tokens.stream().map(e -> {return (SchemeNumber)e;}).collect(Collectors.toList());
- 当我想对一个复杂类进行递归地执行(观察),然后将执行(观察)的结果收集到一个列表里面的时候,该怎么做呢
Tokens.stream().map(e -> e.accept(Executor.this)).collect(Collectors.toList());
- 如果我想实现SchemeArithmetic中的reduce功能,该如何实现呢?
// get the reduce function
BinaryOperator<SchemeNumber> func = (SchemeNumber n1, SchemeNumber n2)
-> new SchemeNumber(n1.getContent() + n2.getContent());
// suppose there is a expr which type is SchemeArithmetic
expr.getContent().stream().reduce(func).get();
- (项目外)如果我想实现类似于python中的range方法,该如何实现呢?
IntStream.range(1, 10);
将其打印出来,如下
IntStream.range(1, 10).forEach(System.out::println);
如果要将其包装成一个List,需要使用boxed()方法对其进行打包
IntStream.range(1, 10).boxed().collect(Collectors.toList());
结语
本长篇幅不多,如果想更好地学习函数式编程,可以在百度里面搜Java8函数式,然后所有IBM的文章就可以,入门很不错,JVM上面可以用scala来学习函数式,如果比较抖M,可以学习Haskell,哈哈哈。