Java8新特性笔记

java8的新特性,Lambda表达式和StreamAPI

一、Lambda表达式

是什么:是一个匿名函数,我们可以把 Lambda 表达式理解为是一段可以传递的代码(将代码像数据一样进行传递)。可以写出更简洁、更灵活的代码。作为一种更紧凑的代码风格,使Java的语言表达能力得到了提升。
语法规则:Lambda 表达式在Java 语言中引入了一个新的语法元素和操作符。这个操作符为 “->” , 该操作符被称为 Lambda 操作符或剪头操作符。它将 Lambda 分为两个部分:
左侧:指定了 Lambda 表达式需要的所有参数
右侧:指定了 Lambda 体,即 Lambda 表达式要执行的功能。
参数->执行代码 速记:左右遇一括号省,左侧推断类型省,能省则省
函数式接口:只有一个抽象方法的接口,检查是否为函数式接口@FunctionalInterface
类型推断:Lambda 表达式中无需指定类型,程序依然可以编译,这是因为 javac 根据程序的上下文,在后台推断出了参数的类型。Lambda 表达式的类型依赖于上下文环境,是由编译器推断出来的。这就是所谓的 “类型推断”

四大核心函数式接口:

  • Comsumer消费型
//有参数无返回值
		Consumer c=(a)->System.out.println(a);
  • Supplier供给型
//无参数列表,无返回值
		Runnable r=()->System.out.println("执行run方法");
  • Optional函数型
//两个参数,多条语句,有返回值
		Comparator<Integer> com=(a,b)->{
			System.out.println("有多条执行语句必须用大括号");
			return Integer.compare(a, b);
		};
  • Predicate断定型
//满足条件的字符串加入集合
	public List<String> predicate(List<String> strs,Predicate<String> p){
		List<String> strings=new ArrayList<>();
		for(String str:strs){
			if(p.test(str)){
				strings.add(str);
			}
		}
		return strings;
	}
	@Test
	public void test4(){
		List<String> ss=Arrays.asList("tom","jack","macho");
		List<String> strs=predicate(ss,a->a.length()>3);
		System.out.println(strs);
	}

方法引用与构造函数引用

方法引用
  • 类名::方法名
@Test
	public void test3(){
		/*BiPredicate<String, String> bp=(x,y)->x.equals(y);
		boolean b=bp.test("tom", "jack");
		System.out.println(b);*/
		BiPredicate<String, String> bp=String::equals;
		boolean b=bp.test("tom", "jack");
		System.out.println(b);
	}
  • 对象名::方法名
emps.stream().map(Employee::getName).forEach(System.out::println);
  • 类::静态方法名
构造器引用
对象引用
//构造器引用
	@Test
	public void test4(){
		/*Supplier<Employee> s=()->new Employee();
		Employee emp=s.get();*/
		Supplier<Employee> s=Employee::new;
		Employee emp=s.get();
		System.out.println(emp);
	}
数组引用
	//数组引用
	@Test
	public void test5(){
		/*Function<Integer, String[]> f=x->new String[x];
		String[] s=f.apply(20);
		System.out.println(s.length);*/
		Function<Integer, String[]> f=String[]::new;
		String[] s=f.apply(20);
		System.out.println(s.length);
	}

二、 StramAPI

是什么:处理集合类似使用sql执行数据库查询
使用步骤

  1. 创建Stream流
  2. 中间操作
  3. 终止操作

步骤一:创建Stream流

方法一:Java8 中的 Collection 接口被扩展,提供了两个获取流的方法:

  • Stream stream() : 返回一个顺序流
  • Stream parallelStream() : 返回一个并行流
List<String> list=new ArrayList<>();
		Stream<String> listStream=list.stream();

方法二:由数组创建流

Java8 中的 Arrays 的静态方法 stream() 可以获取数组流:
static Stream stream(T[] array): 返回一个流
重载形式,能够处理对应基本类型的数组:
public static IntStream stream(int[] array)
public static LongStream stream(long[] array)
public static DoubleStream stream(double[] array)

Employee[] emps=new Employee[10];
		Stream<Employee> eSteam=Arrays.stream(emps);

方法三:由值创建流

可以使用静态方法 Stream.of(), 通过显示值创建一个流。它可以接收任意数量的参数。
public static Stream of(T… values) : 返回一个流。

Stream<String> staticStream=Stream.of("hello","tom","jack");

方法四:由函数创建流,创建无限流

可以使用静态方法 Stream.iterate() 和Stream.generate(), 创建无限流。

Stream<Integer> s=Stream.iterate(0, x->x+2);
		s.limit(10).forEach(System.out::println);
		Stream<Double> generate=Stream.generate(()->Math.random()*100);
		generate.limit(10).forEach(System.out::println);

步骤二:中间操作

  • 筛选,切片,去重
@Test
		public void test(){
			emps.stream().filter(e->{
				System.out.println("执行中间操作");
				return e.getAge()>30;
				//终止操作时才能够执行全部内容,惰性求值
			}).forEach(System.out::println);
		}
		@Test
		public void test2(){
			emps.stream().filter(e->{
				System.out.println("短路");
				return e.getAge()>20;
			})
			.limit(2)
			.forEach(System.out::println);
		}
		@Test
		public void test3(){
			emps.stream().filter(e->e.getAge()>20)
			.skip(3)
			.forEach(System.out::println);
		}
  • 映射
/**
		 * map映射
		 */
		@Test
		public void test5(){
			emps.stream().map(Employee::getName).forEach(System.out::println);
			System.out.println("--------------");
			emps.stream().map(e->e.getName().toUpperCase()).forEach(System.out::println);
		}
  • 排序:默认是自然排序
/**
		 * 排序
		 */
		@Test
		public void test7(){
			emps.stream().sorted((e1,e2)->{
				if(e1.getAge().equals(e2)){
					return e1.getSal().compareTo(e2.getSal());
				}else{
					return e1.getAge().compareTo(e2.getAge());
				}
			}).forEach(System.out::println);
		}

步骤三:终止操作

规约

可以将流中元素反复结合起来,得到一个值。返回 T

	//规约reduce,计算和
		List<Integer> num=Arrays.asList(1,2,4,5);
		Integer sum=num.stream().reduce(0,(x,y)->x+y);
		System.out.println(sum);
		//计算工资总和
		Optional<Integer> totalSal=emps.stream().map(e->e.getSal()).reduce((x,y)->Integer.sum(x, y));
		Optional<Integer> totalSal2=emps.stream().map(Employee::getSal).reduce(Integer::sum);
收集

将流转换为其他形式。接收一个 Collector接口的实现,用于给Stream中元素做汇总的方法。Collector 接口中方法的实现决定了如何对流执行收集操作(如收集到 List、Set、Map)。 Collectors 实用类提供了很多静态方法,可以方便地创建常见收集器实例。

/**
	 * collect汇总总数,平均,总和,最大,最小Collectors.
	 */
	@Test
	public void test3(){
		Long count=emps.stream().collect(Collectors.counting());
		System.out.println(count);
		System.out.println("=================");
		Double average=emps.stream().collect(Collectors.averagingLong(Employee::getSal));
		System.out.println(average);
		System.out.println("=================");
		Long sum=emps.stream().collect(Collectors.summingLong(Employee::getSal));
		System.out.println(sum);
		Optional<Integer> max=emps.stream().map(Employee::getSal).collect(Collectors.maxBy(Integer::compare));
		System.out.println(max.get());
		System.out.println("=================");
		Optional<Employee> min=emps.stream().collect(Collectors.minBy((x,y)->Integer.compare(x.getSal(), y.getSal())));
		System.out.println(min.get().getSal());
		
		
	}
	/**
	 * 分组
	 */
	@Test
	public void test4(){
		//按工作状态分组
		Map<Status,List<Employee>> group=emps.stream().collect(Collectors.groupingBy(Employee::getStatus));
		System.out.println(group);
	}
	/**
	 * 多级分组
	 */
	@Test
	public void test5(){
		Map<Status,Map<String,List<Employee>>> groups=emps.stream().collect(Collectors.groupingBy(Employee::getStatus,Collectors.groupingBy(e->{
			if(((Employee)e).getAge()<25){
				return "青年";
			}else if(((Employee)e).getAge()>=25&&((Employee)e).getAge()<45){
				return "中年";
			}else{
				return "老年";
			}
		})));
		System.out.println(groups);
	}
	/**
	 * 分区
	 */
	@Test
	public void test6(){
		Map<Boolean,List<Employee>> trueorfalse=emps.stream().collect(Collectors.partitioningBy(e->e.getSal()>5000));
		System.out.println(trueorfalse);
	}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值