Java(36):Lambda 与 Stream 小结

2018年10月22日

目录

一、Lambda 

1.1 lambda小例子1

1.2 lambda小例子2

1.3 分析

二、Stream

2.1 如何理解Stream

2.2 Stream特点

2.3 生成Stream的方式

2.4  Stream的中间操作

2.5  Stream的终止操作



Java 是面向对象语言,除了原始数据类型之处,Java 中的所有内容都是一个对象。而在函数式语言中,我们只需要给函数分配变量,并将这个函数作为参数传递给其它函数就可实现特定的功能。

一、Lambda 

Lambda 表达式的加入,使得 Java 拥有了函数式编程的能力。在其它语言中,Lambda 表达式的类型是一个函数;但在 Java 中,Lambda 表达式被表示为对象,因此它们必须绑定到被称为功能接口的特定对象类型。

1.1 lambda小例子1

		new Thread(() -> System.out.println("hello!!")).start();;

输出结果:

hello!!

点击“->”:

 

1.2 lambda小例子2

package LambdaTest;

public  class Lambda2 {
	interface  ITest  { //接口
		int test(String  string);
	}


	static void Print(ITest test) {//接口做对象
		test.test("hello world");
	}


	public static void main(String [] args) {
		Print(string -> {System.out.println(string);
		return 0;}
		);
   }
}

运行结果:

hello world

 

1.3 分析

先来看lambda表达式的语法:

() -> {}
  1. () : 括号就是接口方法的括号,接口方法如果有参数,也需要写参数。只有一个参数时,括号可以省略。(Thread的构造函数接收的是一个Runnable接口对象,而我们这里的用法相当于是把一个函数当做接口对象传递进去了,这点理解很关键,这正是函数式编程的含义所在。

  2. -> :这个箭头是lambda表达式的关键操作符,分割左右部分的,没啥好讲的,作用是:把表达式分成两截,前面是函数参数,后面是函数体。

  3. {} : 要实现的方法体。只有一行代码时,可以不加括号,可以不写return。

  4. 我们注意到Runnable有个注解 @FunctionalInterface,它是jdk8才引入,它的含义是函数接口。它是lambda表达式的协议注解,这个注解非常重要,后面做源码分析会专门分析它的官方注释,到时候一目了然。

 

二、Stream

 

2.1 如何理解Stream

    Stream 不是集合元素,它不是数据结构并不保存数据,它是有关算法和计算的,它更像一个高级版本的 Iterator。
    简单来说,它的作用就是通过一系列操作将数据源(集合、数组)转化为想要的结果。

 

2.2 Stream特点

   Stream 是不会存储元素的。
    Stream 不会改变原对象,相反,他们会返回一个持有结果的新Stream。
    Stream 操作是延迟执行的。意味着它们会等到需要结果的时候才执行。

 

2.3 生成Stream的方式

下面是五种生成stream方法:

		//1. Collection系的 stream() 和 parallelStream();
		ArrayList<Object> list = new ArrayList<>();
		Stream<Object> stream = list.stream();
		Stream<Object> stringStream = list.parallelStream();
		
		//2. 通过Arrays
		Stream<String> stream1 = Arrays.stream(new String[10]);
		
		//3. 通过Stream
		Stream<Integer> stream2 = Stream.of(1,2,3);
		
		//4. 无限流,迭代
		Stream<Integer> iterate = Stream.iterate(0, (x) -> x+22);
		iterate.limit(10).forEach(System.out::println);
		
		//5. 生成
		Stream<Double> generate = Stream.generate(() -> Math.random());
		generate.forEach(System.out::println);
		

 

2.4  Stream的中间操作

		//和map差不多,但返回类型为Stream,类似list.add()和list.addAll()的区别
//		arrayList.stream().map(s -> s+1).forEach(System.out::println);
		arrayList.stream()
		        .map(s -> s + 1)  //映射
		        .flatMap(s -> Stream.of(s)) 
		        .filter(s -> s < 1000)    //过滤
		        .limit(5)   //限制
		        .skip(1)    //跳过
		        .distinct() //去重
		        .sorted()   //自然排序
		        .sorted(Integer::compareTo) //自定义排序
        ;

多个中间操作连接而成为流水线,流水线不遇到终止操作是不触发任何处理的,所为又称为“惰性求值”。

关于map方法,参数为一个Function函数型接口的对象,也就是传入一个参数返回一个对象。这个参数就是集合中的每一项。类似Iterator遍历。其它的几个操作思想都差不多。

执行上面的方法没什么用,因为缺少终止操作。

 

2.5  Stream的终止操作

1.stream常用api

		// 返回流中元素的总个数
		System.out.println(arrayList.stream().count());
		arrayList.stream().allMatch((x) -> x == 555); // 检查是否匹配所有元素
		arrayList.stream().anyMatch(((x) -> x>600)); // 检查是否至少匹配一个元素
		arrayList.stream().noneMatch((x) -> x>500); //检查是否没有匹配所有元素
		arrayList.stream().findFirst(); // 返回第一个元素
		arrayList.stream().findAny(); // 返回当前流中的任意一个元素
		arrayList.stream().count(); // 返回流中元素的总个数
		arrayList.stream().forEach(System.out::println); //内部迭代
		arrayList.stream().max(Integer::compareTo); // 返回流中最大值
		Optional<Integer> min = arrayList.stream().min(Integer::compareTo);//返回流中最小值
		System.out.println("min "+min.get());

 

2.reduce (归约):将流中元素反复结合起来得到一个值

		Integer reduce = arrayList.stream()
		        .map(s -> (s + 100))
		        .reduce(0, (x, y) -> x + y);    
        //归约:0为第一个参数x的默认值,x是计算后的返回值,y为每一项的值。
		System.out.println(reduce);
		
		Optional<Integer> reduce1 = arrayList.stream()
		        .map(s -> (s + 1))
		        .reduce((x, y) -> x + y); 
		// x是计算后的返回值,默认为第一项的值,y为其后每一项的值。
		System.out.println(reduce1);
		

 

3.collect(收集):将流转换为其他形式。需要Collectors类的一些方法。

        Set<Integer> collect = arrayList.stream()
                .collect(Collectors.toSet());
        System.out.println(collect);
        
        List<Integer> collect1 = arrayList.stream()
                .collect(Collectors.toList());
        System.out.println(collect1);

        HashSet<Integer> collect2 = arrayList.stream()
                .collect(Collectors.toCollection(HashSet::new));
        System.out.println(collect2);
        
        //分组 {group=[444, 555, 666, 777, 555]}
        Map<String, List<Integer>> collect3 = arrayList.stream()
                .collect(Collectors.groupingBy((x) -> "group"));//将返回值相同的进行分组
        System.out.println(collect3);

        //多级分组 {group={777=[777], 666=[666], 555=[555, 555], 444=[444]}}
        Map<String, Map<Integer, List<Integer>>> collect4 = arrayList.stream()
                .collect(Collectors.groupingBy((x) -> "group", Collectors.groupingBy((x) -> x)));
        System.out.println(collect4);

        //分区 {false=[444], true=[555, 666, 777, 555]}
        Map<Boolean, List<Integer>> collect5 = arrayList.stream()
                .collect(Collectors.partitioningBy((x) -> x > 500));
        System.out.println(collect5);

        //汇总
        DoubleSummaryStatistics collect6 = arrayList.stream()
                .collect(Collectors.summarizingDouble((x) -> x));
        System.out.println(collect6.getMax());
        System.out.println(collect6.getCount());

        //拼接 444,555,666,777,555
        String collect7 = arrayList.stream()
                .map(s -> s.toString())
                .collect(Collectors.joining(","));
        System.out.println(collect7);

        //最大值
        Optional<Integer> integer = arrayList.stream()
                .collect(Collectors.maxBy(Integer::compare));
        System.out.println(integer.get());

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值