【笔记】 Lambda表达式

Lambda表达式也称为箭头函数,匿名函数,闭包

Lambda表达式体现的是轻量级函数式编程思想 

->符号是Lambda表达式核心操作符号,符号左侧是参数,
右侧是操作表达式

jdk8的新特性

使用Lambda创建线程

	new Thread(() -> {
		// 需要执行的代码
	}).start();

为什么使用Lanbda

  • 它不是解决未知问题的新技术
  • 对现有解决方案的语义优化
  • 需要根据实际需求考虑性能问题

函数式接口

  • 函数式接口就是java类型系统中的接口

  • 函数式接口是只包含一个接口方法的特色接口

  • 语义化检测注解:@FuncionalInterface

  • default方法,static方法不算其中

  • 从Object中继承的方法也不算其中,例如toString()

  • Lambda表达式只能操作一个方法

  • java中Lambda表达式核心就是一个函数式接口的实现

     Lambda针对函数式接口的实现:
     
     A a = (方法的参数) -> {
     
     	// 方法的实现
     };
    

java中内建的函数式接口

  • java.lang.Runable
  • java.lang.Comparable
  • java.lang.Comparator
  • java.io.FileFilter
  • 等等…

jdk8中提供了java.util.function包提供了常用的函数式功能接口

  • java.util.function.Predicate 接受参数T,返回一个Boolean

      Predicate<String> pre = (string name) -> {
      	return "a".equals(name);
      };
      pre.test("a");
    
  • java.util.function.Comsumer 接受参数对象T,没有返回值

      Comsumer<String> cs = (string message) -> {
      	print("接受参数:" + message);
      };
    
  • java.util.function.Function<T, R> 接受对象T,返回对象R

      Function<String, Boolean> funct = (String name) {
      	return "a".equals(name) ? 1 : 0;
      }
    
  • java.util.function.Supplier 不接受参数,提供T对象的创建工厂

      Supplier<String> sp = () -> {
      	return UUID.rendomUUID().toString();
      }
    
  • java.util.function.UnaryOperator 接受参数对象T,返回结果对象T

      UnaryOperator<String> uo = (String img) {
      	return img += "...";
      }
    
  • java.util.function.BinaryOperator 接受两个Td对象,返回一个T 对象结果

      BinaryOperator<Integer> b=(Integer i1,Integer i2) {
      	return i1 > i2 ? li : l2;
      }
    

Lambda表达式的基本语法

  • 声明:就是和Lambda表达式绑定的接口类型

  • 参数:包含在一对圆括号中,和绑定的接口中的抽象方法中的参数

  • 个数及顺序一致

  • 操作符:->

  • 执行代码快:包含在一对大括号中,出现在操作符号右侧

  • [接口声明] = (参数) -> {执行代码块}

    A a = (参数) -> {}
    
    a.方法名();
    

Lambda表达式必须和接口绑定

Lambda表达式的参数可以附带0个到n个参数,括号中的参数类型

可以不用指定,JVM运行是会自动绑定接口中参数的数据类型当有返

回值时,当只有一行代码,可以省略{}和return关键字

匿名内部类中的变量捕获

new Thread(() -> {
	this.成员变量
	局部变量直接访问
}).start();

Lambda的类型检查

test(函数式接口<String, List>)
	test((x, y) -> { 
		y.add(x)
	});

JVM会自动将(x, y) -> { y.add(x)} 绑定为函数式接口类型,
x,y会绑定String, List类型

方法重载两个相同的方法名会使JVN产生混淆,JVM无法判断该调用
那个方法,就会给出编译错误

使用Lambda表达式底层实现是先创建一个静态的方法,方法中实现
逻辑处	理,再创建一个final类型的内部类实现了函数式接口,实现
函

数式的方法,该方法中调用了先前创建的静态方法

Lambda表达式的方法引用

  • 静态方法引用的使用

     类型名称.方法名称 -> 类型名称::方法名称
     
     对象排序:Collections.Sort(对象,(t1, t2)-> 
     
     t1.getAge() - t2.getAge());
     
     使用Lambda表达式Collections.Sort(对象,对象::静态方法)
    
  • 实例方法引用

     A a = new A();
     
     a::方法名();
    
  • 构造方法引用

     A a = A::new;
    
  • Stream是用户处理集合中较为复杂的操作

      过滤 list.stream().fileter(x -> x.length()
      >=5).collect(Collectors.toList());
    

获取stream对象

  • 从集合或数组中获取

     串行 Collections.stream()
     
     并行 Collections.parallelStream()
     
     Arrays.stream(数组对象)
    
  • 从集合或数组中获取

  • 从BufferReader缓冲中获取BufferReader.lines()

  • 静态工厂

     java.util.stream.IntStream.renge()
     
     java.nio.file.files.walk()
    
  • 自定构建

     java.util.Spliterator
    
  • 更多的方式…

     Random.ints()
     
     Pattern.spiltAsStream()...
    

中间操作(返回还是stream())

中间操作可以有一个或者多个连续的中间操作,中间操作只记录操作

方式,不做具体执行,直到结束操作发生时,才做最终执行,中间操作

就是逻辑处理

中间操作过程

  • 无状态:数据处理时,不受前置中间操作的影响

     map/filter/peek/parallel/sequential/unordered
    
  • 有状态:数据处理时,收前置中间操作的影响

  •  distinct/sorted/limit/skip
    

结束操作|终结操作

一个stream()只能有一个终结操作,这个操作一旦发生,就会真实处理

数据,生成对于的处理结果短路操作:当前stream对象必须处理完集合

中的所有数据,才得到结果

forEach/forEachOrdered/toArray/reduce/collect/min/max
/count/iterator

非短路操作

当前的stream对象在处理过程中,一旦满足某个条件,就可以得到结果

anyMatch/allmatch/noneMatch/findFirst/findAny等

Short-circuiting,无限大的Stream -> 有限大的Stream

转换成stream对象

  • stream.of(’’,’’);
  • Arrays.stream();
  • Collections.stream()
  • map.entrySet().stream()
  • IntStream.of(int [])
  • IntStream.range(1,3) 范围查找,包含起始数据不包含结束数据
  • IntStream.rangeClosed(1,3) 范围查找,包含起始数据也包含结束数据

stream转换指定的对象

  • 转换数组

     stream.toArray(String[] ::new); 
    
  • 转换string

     stream.collect(Collectors.joining()).toString();
    
  • 转换List

     stream.collect(Collectors.toList())
    
  • 转换set

      stream.collect(Collectors.toSet())
    
  • 转换map

      stream.collect(Collectors.toMap(x -> x, y -> y))
    

stream常见的api操作

  • 列表中添加一个前缀

      list.stream().map(x -> 'aa' + x).collect
      (Collectors.toList())
    
  • 过滤

      list.stream().fileter(x -> x.length()).collect
      (Collectors.toList())
    
  • forEach

  • list.forEach()

  • peek 中间操作

      ist.stream().peek().peek()....froEach()
    
  • skip 中间操作,有状态的操作,跳过部分数据

      list.stream().skip(3).forEach()
    
  • limit 中间操作,有状态,限制输出数据数量

      list.stream().skip(3).limit(2).forEach
    
  • distinct 中间操作,有状态,剔除重复数据

      list.stream.distinct().forEach
    
  • sorted 中间操作,有状态,排序

  • max 获取最大值

      Optional option = list.stream().max((x, y) -> x-y)
      optional.get()
    
  • min 获取最小值

  • reduce 合并处理数据,求和

      Optional option = list.stream().reduce((sum, x) ->
      sum + x)
      optional.get()
    

parallelStream并行处理原理

将一个大任务拆分成多个小的任务通过多个线程执行的过程

使用parallelStream的forEach会存在线程不安全的情况

线程安全的parallelStream.collect(Collections.toList)

总结

对于简单的数据处理可以使用常规的外部迭代进行处理,如果

对性能有要求可以使用parallelStream进行操作对于复杂对象

的处理操作,stream的迭代操作与普通的迭代操作相差无几,

甚至超过普通的迭代方式,可以使用简洁的stream语法替代

常规迭代操作

如果性能上有要求的话,可以选择parallelStream进行操作
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值