`
xuanzhui
  • 浏览: 197009 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

Lambda表达式之Stream

    博客分类:
  • Java
阅读更多

Java8引入了Stream以实现对集合更方便地进行函数式编程。

Set和List都可以通过stream()方法获取Stream实例;

数组可以通过Arrays.stream(array)工具方法获取Stream实例。

 

对Stream的操作分lazy方法和eager方法:

lazy方法依然返回Stream实例,并没有立马开始计算;

而eager方法相当于正式进入运算阶段,返回的类型由具体方法决定。

 

以下是操作Stream的常见方法,这些方法的操作效果可以参照reactivex编程的数据流图,同一个方法名的操作大体是一致的,何况java reactivex编程和Lambda的结合还是比较紧密的:

RxMarbles -- Interactive diagrams of Rx Observables

Reactivex Operators

 

先定义一个用于测试的类

class Item {
    public String id;
    public int count;

    public Item(String id, int count) {
        this.id = id;
        this.count = count;
    }
}

 

然后初始化了如下三个实例

Item item1 = new Item("it1", 1);
Item item2 = new Item("it2", 2);
Item item3 = new Item("it3", 3);

 

和一个Item列表

List<Item> list = new ArrayList<>();
list.add(item1);
list.add(item2);
list.add(item3);

 

1. forEach -- eager方法,循环对每个元素执行相关指令

list.stream().forEach(item -> System.out.println(item.id));

 这段代码单独放在这边没有什么意义,可以用于下面lazy方法的调试

 

 2. filter -- lazy方法,用于过滤数据

 

list.stream()
    .filter(item -> item.count > 2)
    .forEach(item -> System.out.println(item.id));
输出的结果只包含it3。

 

 

3. map -- lazy方法,用于转变Stream

 

list.stream()
    .map(item -> item.id)   //从Item的Stream转变成了String的Stream
    .forEach(System.out::println);
 类似的还有mapToInt、mapToLong、mapToDouble,传入的lambda或者函数应该返回int、long、double类型的数据,转换成的Stream依次为IntStream、LongStream、DoubleStream,这些类型的Stream有自己专有的成员函数用于简化相关的计算,例如sum()返回加和。

 

 

4. flatMap -- lazy方法,用于将多个Stream转换成一个Stream

 

Arrays.stream(new String[]{"A,B,C", "D,E"})
      .flatMap(s -> Arrays.stream(s.split(",")))
      .forEach(System.out::println);
 flatMap中的lambda或函数需要返回Stream,这边将字符串数组中的每个字符串按逗号切分转换成了两个Stream,然后flatMap将这两个Stream合并成了一个大的Stream;flatMap也有map类似的三个的额外方法。

 

 

5. reduce -- eager方法,实现从一组值中生成一个值

OptionalInt sum = Arrays.stream(new int[]{1, 2, 3})
				.reduce((left, right) -> left + right);
System.out.println(sum.orElse(0));

 这边通过reduce实现求知的效果,由于没有设置初始值,所以返回的是一个Optional类型的对象,该对象的作用在于警示有可能返回的值不存在,需要先判断再取值。

 

进一步演示通过reduce查找Item列表中count最大的元素

Item res = list.stream()
        .reduce(item1, (left, right) -> left.count > right.count ? left : right);
System.out.println(res.id);	

 reduce中传入的lambda或函数应该起到两个元素变成一个的作用。

 

6. sum、count、min、max -- eager方法,可以认为是封装reduce后的常用方法

Optional<Item> min = list.stream()
	.min(Comparator.comparingInt(item -> item.count));

 

7. collect -- eager方法,用于将Stream转换成集合或Map

Set<Integer> set = list.stream()
                .filter(item -> item.count > 2)
                .map(item -> item.count)
                .collect(Collectors.toSet());

 collect还有其他高阶的用法,之后再补充

 

以上都只演示了比较简单的处理逻辑,对于复杂的逻辑可以写在函数中,然后将该函数作为相关方法的参数。

 

关于引入Stream对java语法的影响:

1. interface里面可以实现方法,但是必须用default修饰

比如Collection中生成Stream的接口,主要还是为了兼容以前的代码

default Stream<E> stream() {
    return StreamSupport.stream(spliterator(), false);
}

 

The Three Rules

 

If you’re ever unsure of what will happen with default methods or with multiple inheritance of behavior, there are three simple rules for handling conflicts:

 

1. Any class wins over any interface. So if there’s a method with a body, or an abstract declaration, in the superclass chain, we can ignore the interfaces completely.

2. Subtype wins over supertype. If we have a situation in which two interfaces are competing to provide a default method and one interface extends the other, the subclass wins.

3. No rule 3. If the previous two rules don’t give us the answer, the subclass must either implement the method or declare it abstract.

 

Rule 1 is what brings us compatibility with old code.

 

2. interface里面可以有static方法

比如Stream.of()

public static<T> Stream<T> of(T... values) {
    return Arrays.stream(values);
}

 

 

 

 

分享到:
评论

相关推荐

    Stream、Lambda表达式练习.doc

    Stream、Lambda表达式练习.doc

    【Java8】Lambda表达式 和 Stream API 详解笔记.zip

    视频地址:https://www.bilibili.com/video/BV1ut411g7E9 【Java8】Lambda表达式 和 Stream API 详解笔记 md文档

    Lambda表达式和stream流的入门

    Lambda表达式和stream流的入门 java 响应式编程

    JDK8特性(Lambda表达式+StreamAPI简单示例代码)

    JDK8特性(Lambda表达式+StreamAPI的简单使用示例代码)

    06.第六节-如何精简lambda表达式.mp4

    Java8发布到现在至少3年了,但是对Lambda表达式不熟悉、看不懂、不会用的现象非常...本系列课程从Lambda表达式、方法的引用、Stream API三处着手分析Lambda表达式的使用。 通过大量的实战例子讲解如何使用Lambda表达式

    Stream和Lambda表达式最佳实践

    Stream和Lambda表达式是Java 8引入的两个重要特性,它们极大地简化了集合处理和函数式编程的复杂性。以下是关于Stream和Lambda表达式的最佳实践介绍: Lambda表达式 Lambda表达式允许我们以简洁的方式表示匿名函数...

    Java 8 新特性详细介绍Lambda表达式、Stream API、接口的默认方法

    Lambda表达式、Stream API、接口的默认方法等功能极大地简化了代码的编写和阅读。新的日期/时间API和CompletableFuture等特性则提供了更好的功能支持和性能优化。通过学习和应用Java 8的新特性,开发者能够更加高效...

    Lambda表达式的相关用法

    Lambda and Anonymous Classes(I),展示如何使用Lambda表达式替代匿名内部类,说明Lambda表达式和函数接口的关系。 Lambda and Anonymous Classes(II),Lambda表达式的实现原理 Lambda and Collections,学习Java...

    10.第十节-使用lambda表达式实现排序.mp4

    Java8发布到现在至少3年了,但是对Lambda表达式不熟悉、看不懂、不会用的现象非常...本系列课程从Lambda表达式、方法的引用、Stream API三处着手分析Lambda表达式的使用。 通过大量的实战例子讲解如何使用Lambda表达式

    08.第八节-使用lambda表达式创建线程.mp4

    Java8发布到现在至少3年了,但是对Lambda表达式不熟悉、看不懂、不会用的现象非常...本系列课程从Lambda表达式、方法的引用、Stream API三处着手分析Lambda表达式的使用。 通过大量的实战例子讲解如何使用Lambda表达式

    09.第九节-使用lambda表达式遍历集合.mp4

    Java8发布到现在至少3年了,但是对Lambda表达式不熟悉、看不懂、不会用的现象非常...本系列课程从Lambda表达式、方法的引用、Stream API三处着手分析Lambda表达式的使用。 通过大量的实战例子讲解如何使用Lambda表达式

    Lambda表达式和StreamAPI学习总结.pdf

    Java8新特性初级入门学习

    04.第四节-什么是lambda表达式概念.mp4

    Java8发布到现在至少3年了,但是对Lambda表达式不熟悉、看不懂、不会用的现象非常...本系列课程从Lambda表达式、方法的引用、Stream API三处着手分析Lambda表达式的使用。 通过大量的实战例子讲解如何使用Lambda表达式

    05.第五节-lambda表达式语法的介绍.mp4

    Java8发布到现在至少3年了,但是对Lambda表达式不熟悉、看不懂、不会用的现象非常...本系列课程从Lambda表达式、方法的引用、Stream API三处着手分析Lambda表达式的使用。 通过大量的实战例子讲解如何使用Lambda表达式

    JAVA8新特性Lambda表达式、Stream使用

    需要环境:JDK8 下载下来后 直接导入IDE工具中,运行TestLambda、TestLambda2、TestLambda3、PracticeLambda、TestStream中的main方法就可以看见结果

    函数式编程以及lambda表达式Stream流技术分享PPT

    该PPT为本人翻遍大部分帖子、博客、资源等一系列资料自我整合了一套技术分享PPT,以Java为载体,概括了Lambda表达式的使用概念、函数式编程的思想,以及Stream流的各个方法的使用,Stream流的强大功能等。

    Android 中Lambda表达式的使用实例详解

    Java8 中着实引入了一些非常有特色的功能,如Lambda表达式、streamAPI、接口默认实现等等。Lambda表达式在 Android 中最低兼容到 Android2.3 系统,兼容性还是不错的,Lambda表达式本质上是一种匿名方法,它既没有...

    精通lambda表达式:Java多核编程(只有两章).pdf

    这是中文版的介绍java8新特性的书,lambda、Stream、接口default,且只有前两章内容。原英文版下载链接:http://download.csdn.net/download/houxuehan/9648087

    jdk8 新特性stream 和lambda表达式Demo

    jdk8 新特性stream 和lambda表达式Demo

    java8源码-LambdaExpression:Lambda表达式

    Lambda表达式 Lambda表达式是一个匿名方法,将行为像数据一样进行传递。 Lambda 表达式常见的结构: BinaryOperator add = (x,y) -&gt; x+y; 函数接口指仅具有单个抽象方法的接口,用来表示Lambda表达式的类型。 Lambda...

Global site tag (gtag.js) - Google Analytics