Java8新特性-Lambda表达式

Lambda基础语法

语法格式1:无参数,无返回值
() -> System.out.println("Hello Lambda!");
语法格式2: 有一个参数,无返回值
(x) -> System.out.println(x);
语法格式3:只有一个参数,小括号可以不写
x -> System.out.println(x);
语法格式4:有两个以上参数,有返回值,并且Lambda体中有多条语句
Comparator<Integer> com = (x,y) -> {
			System.out.println("Hello Lambda");
			return Integer.compare(x,y);	
};
语法格式5:若Lambda体重只有一条语句,return和大括号可以神略不写
Comparator<Integer> com = (x,y) -> Integer.compare(x,y);	
语法格式6:Lambda 表达式的参数列表的数据类型可以省略不写,因为JVM编译器通过上下文推断出数据类型,即“类型推断”
(Integer x,Integer y) -> Integer.compare(x,y);	
小结:
上联:左右遇一括号省
下联:左侧推断类型省
横批:能省则省
Lambda表达式需要“函数式接口”的支持
函数式接口:接口中只有一个抽象方法的接口,称为函数式接口。可以使用注解@FunctionalInterface修饰来判断是否为函数式接口
Java8 内置的四大核心函数式接口
  • Consumer :消费型接口
    void accept(T t)
Consumer<Double> consumer= (x) -> System.out.println("今天消费了" + x + "元");
consumer.accept(100.0);
  • Supplier:供给型接口
    T get();
Supplier<Integer> supplier = () -> (int) (Math.random() * 100);
System.out.println(supplier.get());
  • Function<T,R>:函数型接口
    R apply(T t)
Function<String, String> fucFunction = (str) -> str.trim();
String str = "\t\t\t 你好啊Lambda   ";
System.out.println("原来的字符串:" + str);
String result = fucFunction.apply(str);
System.out.println("处理后的字符串:" +result);
  • Predicate :断言型接口
    boolean test(T t)
Predicate<String> predicate = (str) -> str.equals("aa");
System.out.println(predicate.test("aa"));
System.out.println(predicate.test("bb"));

方法引用

若Lambda体中的内容有方法已经实现了,我们可以使用“方法引用”
(可以理解为方法引用是Lambda表达式的另一种表现是形式)
主要有三种语法格式:
对象 :: 实例方法名(不需要加括号)
类 :: 静态方法名(不需要加括号)
类 :: 实例方法名(不需要加括号)

注意:
	1.Lambda提中调用方法的参数列表与返回值类型,要与函数式接口中的抽象方法的函数列表和返回值要保持一致
	2.若Lambda参数列表中的第一个参数是实例方法的调用者,第二个参数是实例方法的参数,可以使用ClassName :: method
Employee emp = new Employee();
Supplier<String> sup = () -> emp.getName();
System.out.println(sup.get());
// 使用方法引用 -> 对象 :: 实例方法名(不需要加括号)
Supplier<String> sup2 = emp::getName;
System.out.println(sup2.get());

// 使用方法引用 -> 类 :: 静态方法名(不需要加括号)
Comparator<Integer> com = (x,y) -> Integer.compare(x,y);
Comparator<Integer> com1 = Integer::compare;

// 使用方法引用 -> 类 :: 实例方法名(不需要加括号)
BiPredicate<String ,String> bp = (x,y) -> x.equals(y);
BiPredicate<String ,String> bp2 = String :: equals;// 当第一个参数是方法的调用者,第二个参数时该方法的参数,则可以使用: 类 :: 实例方法名

构造器引用

  • 格式:
    ClassName :: new
Supplier<Employee> sup = () -> new Employee();
Supplier<Employee> sup1 = Employee::new;// 自动匹配Supplier的参数列表,这个接口有几个参数,就调用几个参数的构造器

数组引用

  • 格式:
    Type :: new;
Function <Integer,String[]> fun = (x) -> new String[x];
String[] strs = fun.apply(10);
System.out.println(Strs.length());

Function <Integer,String[]> fun2 = String::new; 
String[] strs2 = fun2.apply(20);
System.out.println(Strs2.length());

Stream(流)

  • 是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列

  • (集合讲的是数据,流讲的是计算)

  • 注意

      Stream自己不会存储元素。
      Stream不会改变源对象。相反,他们会返回一个持有结果的新Stream
      Stream操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。
    
Stream的操作三个步骤
  1. 创建Stream

    一个数据源(如:集合、数组),获取一个流
    
  2. 中间操作

    一个中间操作链,对数据源的数据进行处理
    多个中间操作可以连接起来形成一个流水线,除非流水线上触发终止操作哦,否则中间操作不会执行任何处理!而在终止操作时一次触发全部处理,称为:惰性求值
    
方法描述
filter(Predicate p)接收Lambda,从流中排除某些元素
distinct()筛选,通过流所生成元素的hasCode()和equals()去除重复元素
limit(long maxSize)截断流,使其元素不超过给定数量
skip(long n)跳过元素,返回一个扔掉了前n个元素的流。若流中元素不足n个,则返回一个空流。与limit(n)互补
  1. 终止操作(终端操作)

    一个终止操作,执行中间操作链,并产生结果
    
public void test1(){
	// 1.通过Collection系列集合提供的stream()或parallelStream()
	List<String> list = new ArrayList<>();
	Stream<String> stream1 = list.stream();

	// 2.通过Arrays中的静态方法stream()获取数组流
	Employee[] emps = new Employee[10];
	Stream<Employee> stream2 = Arrays.stream(emps);

	// 3.通过Stream类中的静态方法of()
	Stream<String> stream3 = Stream.of("aa","bb","cc");

	// 4.创建无限流
	// 迭代
	String<Integer> stream4 = Stream.iterate(0,(x) -> x + 2);
	stream4.limit(10).forEach(System.out::prinltn);
	
	// 生成
	Stream.generate(() -> Math.random())
					.limit(5)
					.forEach(System.out::println);
	
}
public void test2(){
	// 中间操作:不会执行任何操作,只有执行了终止操作才会执行
	Stream<Employee> stream = employees.stream()
										.filter((e) -> e.getAge() > 35);
	stream.forEach(System.out::println);						
}

// 内部迭代由stream API 完成
// 外部迭代
public void test3(){
	Iterator<Employee> it = employee.iterator();
	while(it.hasNext()){
		System.out.println(it.next);
	}
}
映射
  • map - 接收Lambda,将元素转换成其他形式或提取信息,接收一个函数作为参数,该函数会被应用 到每个元素上,并将其映射成一个新的元素。
  • flatMap - j接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流
public void test5(){
	List<String> list = Arrays.asList("aa","bb");
	list.stream()
		.map((str) -> str.toUpperCase())
		.forEach(System.out::println);
	employees.stream()
			 .map(Employee::getName)
			 .forEach(System.out::println);
}
Optional类
  • Optional 容器类常用的方法:

      Optional.of(T t): 创建一个Optional实例
      Optional.empty() : 创建一个空的Optional实例
      Optional.ofNullable(T t) : 若t不为null,创建Optional实例,否则创建空实例
      isPresent() : 判断是否包含值
      orElse(T t) : 如果调用对象包含值,则返回该值,否则返回t
      orElseGet(Supplier s) : 如果调用对象包含值,则返回该值,否则返回s获取的值
      map(Function f) : 如果有值对其处理,并返回处理后的Optional.empty()
      flatMap(Function mapper) : 与map类似,要求返回值必须是Optional
    

未完,待续。。。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值