JDK 1.8 新特性

1Lambda 表达式

Lamdba 表达式是一种没有名字的函数,也可称为闭包,是JAVA 8 发布的中重要新特性

本质上上一段匿名内部类。也可以是一段可以传递的代码,还有叫箭头函数的

闭包:

闭包就是能够读取其他函数内部变量的函数,比如在java中 方法内部的局部变量 只能在方法内部使用,所以闭包可以理解为定义在一个函数内部的函数

闭包的本质就是将函数内部和函数外部链接起来的桥梁

1.2 lambda 特点

允许把函数作为一个方法的参数(函数作为参数传递进方法中)

使用Lambda 表达式可以使代码变得更加简洁紧凑

lambda 和匿名内部类对比

​
	Integer[] arr = {1,2,5,3,8,45,3};
		//asList: 把数组转换为List集合
		List<Integer> integers = Arrays.asList(arr);
		//匿名内部类写法
//		Collections.sort(integers, new Comparator<Integer>(){
//			public int compare(Integer o1,Integer o2){
//				return o2-o1;
//			}
//		});
		//lambda
		Collections.sort(integers, (i1,i2) -> i2-i1);
		System.out.println(integers);
	}

​

1.3 lambd 应用场景

1)列表迭代 2)Map映射 3)Reduce 聚合 4)代替一个不想命名的函数或是类,该函数或类往往并不复杂 4)想尽量缩短代码量的各个场景均可以

1.4.1具体语法:

        (parameters) -> expression

        (parameters) ->{statements;}

1.4.2语法特点

        

可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。

可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。可选的大括号:如果主体包含了一个语句,就不需要使用大括号。可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值 如果只有一条语句,并且是返回值语句,就可以不写return 不写 {} 

如果写上{}  就必须写return 和 ;

如果有 多条语句,必须写{}  return 和 ;  也必须写

案例说明-简单

// 1. 不需要参数,返回值为 5 

() -> 5 

// 2. 接收一个参数(数字类型),返回其2倍的值 

x -> 2*x 

// 3. 接受2个参数(数字),并返回他们的差值 

(x, y) -> x – y 

// 4. 接收2个int型整数,返回他们的和 

(int x, int y) -> x + y 

// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void) 

(String s) -> System.out.print(s)

2 函数式接口

2.1介绍

其本质是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。核心目标是为了给Lambda表达式的使用提供更好的支持,进一步达到函数式编程的目标,可通过运用函数式编程极大地提高编程效率。其可以被隐式转换为 lambda 表达式。

2.2特点:

函数式接口是仅制定一个抽象方法的接口

可以包含一个或多个静态或默认方

专用注解即@FunctionalInterface 检查它是否是一个函数式接口,也可不添加该注解

如果有两个或以上 抽象方法,就不能当成函数式接口去使用,也不能添加@FunctionalInterface这个注解

如果只有一个抽象方法,那么@FunctionalInterface注解 加不加 都可以当做函数式接口去使用

 2.3代码实现

 * Supplier 接口 有一个get方法 用于获取数据
 
public class FunInterface_01 {
	public static int sum(Supplier<Integer>sup){
		return sup.get();
	}
	public static void main(String[] args){
		int result = sum(()->1+2);
		System.out.println(result);
	}
}
package FunInterface;

import java.util.function.Consumer;

public class FunInterface_02 {
	public static void print(Consumer<String> con,String msg){
		con.accept(msg);
	}
	public static void main(String[] args){
		print((str) -> System.out.println(str), "你好吗");
	}
}

3.1 方法引用

对象引用:: 成员方法
 *要求: 使用接口的抽象方法的入参和出参,必须和调用方法的入参出参一致



public class FunCall_01 {
	public static void main(String[] args){
		Integer i1 = 10;
		//方法调用
		String str = i1.toString();
		System.out.println(str);
		//lambda 表达式写法
		Supplier<String> su = ()->i1.toString();
		System.out.println(su.get());
		//方法引用写法
		Supplier<String> su1 = i1::toString;
		
		
	}
}

类名 ::静态方法名

public class FunCall_02 {
	public static void main(String[] args){
		int max = Integer.max(11,21);
		BiFunction<Integer,Integer,Integer> bf = Integer::max;
		System.out.println(bf.apply(11, 21));
	}
}

 类名:: 成员方法

public class FunCall_03 {
	public static void main(String[] args){
		BiPredicate<String,String> bp = String::equals;
		System.out.println(bp.test("axz", "axz"));
	}
}

 创建对象

public class FunCall_04 {
		public static void main(String[] args){
			Object o1 = new Object();
			Supplier<Object> sp = Object::new;
			System.out.println(sp.get());
		}
}

4 Stream API

4.1概念说明 

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

        集合讲的是数据,流讲的是计算,即一组用来处理数组,集合的API

4.2

                Stream 不是数据结构,没有内部存储,自己不会存储元素。

               Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream。

               Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。

               不支持索引访问。

               延迟计算

               支持并行

               很容易生成数据或集合

               支持过滤,查找,转换,汇总,聚合等操作

4.3 运行机制说明

Stream分为源source,中间操作,终止操作。

 流的源可以是一个数组,集合,生成器方法,I/O通道等等。

 一个流可以有零个或多个中间操作,每一个中间操作都会返回一个新的流,供下一个操作使用,一个流只会有一个终止操作。

 中间操作也称为转换算子-transformation

Stream只有遇到终止操作,它的数据源会开始执行遍历操作。

  终止操作也称为动作算子-action

因为动作算子的返回值不再是 stream,所以这个计算就终止了

只有碰到动作算子的时候,才会真正的计

4.4代码实现

public static void main(String[] args){
		//1数组,通过stream 类的of 方法即可
		String[] strings = {"a","b","c","d"};
		Stream<String> stream1 = Stream.of(strings);
		
		//2集合    通过集合对象的stream 方法即可
		List<String> strings2 = Arrays.asList(strings);
		Stream<String> stream2 = strings2.stream();
	
		//3 通过Stream 的generate方法创建无限流
		//该流无限大,建议使用limit 限制条数
		//参数是一个Supplier 接口,有一个get方法,无参,有返回值
		//返回的数据就会被放到这个无限流中,也就是目前这个流中的数据都是1
		Stream<Integer> stream3 = Stream.generate(() ->1);
		stream3.limit(8).forEach(x ->System.out.println(x));
		
		//4 通过Stream.iterate 方法创建无限流
		//第一个参数是起始值,第二个参数是UnaryOperator, 是 function 的子类,所以是有参返回值
		// x-> x+2 : 等于步长为2, 那么此时,数据流中内容1,3,5.......
		Stream<Integer> stream4 = Stream.iterate(1, x ->x+2);
		stream4.limit(7).forEach(x-> System.out.println(x));
	
		//5 已有类的streamAPI
		String string = "sadas";
		IntStream is = string.chars();
		is.forEach(x ->System.out.println(x));
	}
public static void main(String[] args){
		List<String> strings = Arrays.asList("a","b","c","a","d");
		/**
		 * filter: 对元素进行过滤,不符合条件的就不要了
		 */
		Stream<String> stream = strings.stream();
		//collect: 收集器,把流转换为集合
		// x-> !x.equals("a") 只要不是a的
		List<String> result = stream.filter(x->!x.equals("a")).collect(Collectors.toList());
		System.out.println(result);
		//流一旦使用过,必须重新生成,否则报错,所以每个中间操作都是返回一个新的流,因为原来的流不能用了
		
		/**
		 * distinct 去除重复
		 */
		stream = strings.stream();
		result = stream.distinct().collect(Collectors.toList());
		System.out.println(result);
		
		/**
		 * map
		 */
		List<Integer> says = Arrays.asList(2000,1000,1500,7300,5000);
		Stream<Integer> stream1 = says.stream();
		//所有人张薪资百分之十
		says = stream1.map(x-> x+x/100*10).collect(Collectors.toList());
		System.out.println(says);
		
		/**
		 * sorted 排序
		 */
		stream1 = says.stream();
		//默认是升序
		//says = stream1.sorted((x,y) ->x-y).collect(Collectors.toList());
		//降序
		says = stream1.sorted((x,y) ->y-x).collect(Collectors.toList());
		System.out.println(says);
	}
* 终止操作  又称为动作算子
 * forEach 循环遍历
 * collect 收集器
 * 计算相关: min,max,count,avrage
 *  匹配相关: anyMatch, allMatch....

 */
public class Stream_03 {
	public static void main(String[] args){
		List<String> strings = Arrays.asList("a","b","c","a");
		//forEach
		Stream<String> stream = strings.stream();
		stream.forEach(x -> System.out.println(x));
		
		//统计
		stream = strings.stream();
		//统计元素个数,一般需要和中间操作结合使用,否则还不如使用集合的size方法
		long count = stream.count();
		System.out.println(count);
		
		//比如 统计有多少个a
		stream = strings.stream();
		//统计元素个数,一般需要和中间操作结合使用,
		count = stream.filter(x ->x.equals("a")).count();
		System.out.println(count);
		
		//最大值max 最小值min
		List<Integer> list = Arrays.asList(1,3,2,6,53);
		Stream<Integer> stream1 = list.stream();
		int max =stream1.max((x,y)->x-y).get();
		System.out.println(max);
		
		//匹配相关anyMath 匹配数据 比较是否包含
		stream1 = list.stream();
		//这种需求 contains 就能解决,但是也有contains解决不了的
		boolean result = stream1.anyMatch(x->x==5);
		System.out.println(result);
		
		//比如所有学生中。判断是否又19岁的
		List<Student> students = new ArrayList<Student>();
		students.add(new Student("张三",20));
		students.add(new Student("李四",22));
		students.add(new Student("王三",21));
		students.add(new Student("马刘",19));
		Stream<Student> stream2 = students.stream();
		result = stream2.anyMatch(s->s.age==19);
		System.out.println(result);
		}
}
class Student{
	String name;
	int age;
	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值