很早就想仔细学了,终于有机会记一下笔记……
只定义了一个 抽象 方法的的接口,值得注意的是,Java 8 引入了 stream 等方法,但是原先的 Collection 里没有。为了提高效率,接口的设计者就引入了 default 关键字来扩充接口。可用 @FunctionalInterface 标记为函数式接口,类似 @Override。
sout
其实 Java 中就是一个接口实现,如果要扯到函数式编程的话就要扯到 lambda 演算,主要为三条规则:
我的理解是这三条规则为定义一个变量和函数,然后告诉你定义完了怎么去使用它
举个难一点的栗子(PS:为什么要举难一点的例子……
)
(lambda x y. x y) (lambda z . z * z) 3
从支持数据处理操作的源生成的元素序列
用过的人都说好……
内部迭代
将迭代封装在内部,例如
Dish.menu.stream().map(Dish::toString).collect(Collectors.toList()); Dish.menu.stream().forEach(System.out::println);
使用规则
// Stream.of Stream.of("Java 8", "Lambdas", "In", "Action").map(String::toUpperCase).forEach(System.out::println); // Stream.empty Stream<String> emptyStream = Stream.empty(); // Arrays.stream int[] numbers = {2, 3, 5, 7, 11, 13}; System.out.println(Arrays.stream(numbers).sum());
flatMap
将流中的每个值都换成另一个流,然后把所有的流连接起来成为一个流,个人理解为将流里的值继续转换为子流然后连接。
List<Integer> list1 = Arrays.asList(1, 2, 3); List<Integer> list2 = Arrays.asList(4,5); list1.stream().flatMap(i-> list2.stream().map(j->new int[]{i,j}) ).forEach(t-> System.out.println(t[0]+","+t[1]));
mapToInt
短路操作,找到一个符合条件的立即返回
使用 reduce,第一个参数为初始值,第二个为执行函数直到规约到一个数
数值流以及对象流相互的转化
int calories = menu.stream().mapToInt(Dish::getCalories).sum(); menu.stream().mapToInt(Dish::getCalories).boxed();
数值范围
rangeClosed
long count = IntStream.rangeClosed(1, 100).filter(d -> d % 2 == 0).count();
range
不包括结束值
前面的都是小儿科,在开发人员的代码里很多都是收集器
通过 reducing() 实现,需要三参数,单参数为三参数的特殊情况,起点为第一个项目,转换函数为恒等函数,第三个为函数计算
menu.stream().map(Dish::getName).collect(joining()); menu.stream().map(Dish::getName).collect(reducing((s1,s2)->s1+s2)).get(); menu.stream().collect(reducing(" ",Dish::getName,(s1,s2)->s1+s2));
groupingBy
特殊的分组,分区函数返回 boolean
Supplier<A> supplier() BiConsumer<A, T> accumulator() Function<A, List<T>>() BinaryOperator<A> combiner() Set<Characteristics> characteristics()
单纯的能看懂……
PS:如果想提高效率,自行实现 Spliterator 接口
未完待续……