Java基础Day26

day26—JDK8新特性

  1. Lambda表达式
  2. Lambda表达式的作用 : 主要就是简化匿名内部类对象的实现过程
    匿名内部类 : 可以作为一个类的子类或者是一个接口的实现类存在
  3. Lambda表达式的实现方式
  1. 符号 : -> , 叫做箭头运算符,也叫做Lambda运算符
  2. -> 的作用 : 将需要重写的方法分成两部分
    -> 的左边部分,表示需要重写方法的参数列表
    -> 的右边部分,表示需要重写的方法的实现过程(实现逻辑)
  3. Lambda实现的语法格式:
  1. 需要重写的方法,没有参数,也没有返回值类型,并且实现语句只有一句
    ()->System.out.println(“打印”);

  2. 需要重写的方法,有1个参数,没有返回值类型,并且实现语句只有一句
    (x)->System.out.println(xx);
    注意 : 如果Lambda表达式中的参数只有一个,那么小括号可以省略
    x ->System.out.println(x
    x);

  3. 需要重写的方法,多个参数,没有返回值类型
    (x,y)->System.out.println(x*y);
    (x,y)->{
    可以写任意的逻辑语言
    }
    注意: 如果Lambda表达式重写的方法,方法内容有多句,将多条语句放到大括号中即可

  4. 需要重写的方法,多个参数,有返回值类型,并且实现语句多条
    (x,y,z)->{
    // 写方法的实现逻辑
    return 数值;
    }
    注意: 如果lambda表达式的重写内容只有一句话,省略大括号
    如果这一句话就是return的结果,那么return也一起省略掉

Lambda语法格式1代码
package com.zgjy.lambda;
public class LambdaDemo1 {
public static void main(String[] args) {
lambda1();
}

// 1. lambda表达式实现没有参数没有返回值类型的接口
public static void lambda1() {
	
	// 1. 创建一个匿名内部类对象实现接口MyInter1
		MyInter1 my = new MyInter1() {
			@Override
			public void fun() {
				System.out.println("匿名内部类实现的接口MyInter1");
			}
		};
		my.fun();
						
	// 2. Lambda表达式实现接口MyInter1
	// Lambda表达式可以实现的接口,接口中只能有一个抽象方法
	// Lambda表达式替代简化了匿名内部类的实现过程
	  MyInter1 my1 = () -> System.out.println("Lambda表达式实现的接口MyInter1");
	  my1.fun();
}

}

// 定义一个接口
interface MyInter1{
// 定义一个抽象方法
// 没有返回值类型,没有参数
public abstract void fun();
}

Lambda语法格式2代码
package com.zgjy.lambda;
public class LambdaDemo2 {
public static void main(String[] args) {
// 1. 使用匿名内部类对象的方式实现接口MyInter2
MyInter2 my2 = new MyInter2() {

		@Override
		public void fun2(int x) {
			System.out.println(x+x);
		}
	};
	my2.fun2(5);// 10
	
	// 2. 使用lambda表达式方式实现接口MyInter2
	// 带有一个参数,没有返回值类型
	MyInter2 my = (y)-> System.out.println(y*y);
	my.fun2(10);//100
	
	// Lambda表达式的参数列表只有一个,小括号可以省略
	MyInter2 my1 = y -> System.out.println(y*y);
	my.fun2(8);//64
}

}
interface MyInter2{
//定义一个带有一个参数,没有返回值类型的抽象方法
public abstract void fun2(int x);
}

Lambda语法结构3代码
package com.zgjy.lambda;
public class LambdaDemo3 {
public static void main(String[] args) {
// 1. 匿名内部类对象实现MyInter3接口
MyInter3 my= new MyInter3() {

			@Override
			public void fun3(int x, int y) {
				int w = x +y;
				System.out.println(w);	
			}	
		};
		
		my.fun3(5, 10);// 15
		
		// 2. Lambda表达式实现MyInter3接口
		MyInter3 my1 = (x,z)->System.out.println(x*z);
		my1.fun3(2, 6);// 12
		
		// Lambda表达式的方法重写逻辑多条语句,使用大括号包裹
		MyInter3 my2 = (w,y)->{
			int q = w + y;
			System.out.println(q*2);
		};
		
		my2.fun3(1, 2);// 6		
}

}

interface MyInter3{
// 定义抽象方法,有多个参数,没有返回值类型
public abstract void fun3(int x , int y);
}

Lambda语法格式4代码
package com.zgjy.lambda;
public class LambdaDemo4 {
public static void main(String[] args) {
// 1. 匿名内部了对象实现接口MyInter4
MyInter4 my = new MyInter4() {

		@Override
		public int fun4(int x, int y, int z) {
			// TODO Auto-generated method stub
			return 0;
		}	
	};
	
	System.out.println(my.fun4(1, 2, 3));// 0
	
	// 2. lambda表达式实现接口MyInter4
	MyInter4 my1 = (x,y,z)->{
		int w = x + y + z;
		return w;	
	};
	
	System.out.println(my1.fun4(1, 2, 3));// 6
	
	// 如果lambda表达式的重写内容只有一句话,省略大括号
	// 如果这一句话就是return的结果,那么return也一起省略掉
	MyInter4 my2 = (x,y,z)->x+y+z;
	System.out.println(my2.fun4(5, 10, 15));// 30
}

}
interface MyInter4{

//定义抽象方法,多个参数,带有返回值类型
public abstract int fun4(int x,int y,int z);	

}

  1. 函数式接口
    2.1 函数式接口的概念
  2. 什么叫做函数式接口?
    定义一个接口,这个接口中只有一个抽象方法,那么这个接口称为函数式接口
  3. Lambda表示式,就是为了实现函数式接口
  4. 函数式接口的作用:
    有些其他类的编程语言中,支持一种数据类型叫做函数,函数对应java中的方法,于是其他语言中函数可以作为参数传递,但是Java不行,因为java中的方法不是一种数据类型,不能单独存在,于是将这个函数(方法)封装到一个接口中,那么传递这个接口,就相当于在传递这个函数内容
    方法表示的是一种实现过程,有一些的场景下,需要将实现过程作为一个参数传递,传递的是一种思想,二不是简单的数值
  5. 如何判断一个接口是函数式接口?
    引入一个注解 @FunctionalInterface , 在定义的接口之上使用注解,如果接口不报错,证明是一个函数式接口,报错,证明不是函数式接口

2.2 常用的内置函数式接口

  1. Consumer : 消费型接口
    方法 : accept(T t) : 就是将给出的参数t进行消费,Java中的消费就是指使用,可以任意的使用这个变量t,不需要返回值类型

  2. Supplier : 供给型接口
    方法 : T get() : 不需要参数,直接给出一个结果

  3. Function<T,R> : 函数式接口
    方法 : R apply(T t) : 提供参数类型t,返回结果类型R

  4. Predicate : 断言型接口
    方法 : boolean test(T t) : 提供一个数据t,将t是否符合规则结果输出

2.3消费型接口
Consumer : 消费型接口
方法 : accept(T t) : 就是将给出的参数t进行消费,Java中的消费就是指使用,可以任意的使用这个变量t,不需要返回值类型

代码
package com.zgjy.interfaceDemo;
import java.util.function.Consumer;
// 消费型接口的使用案例
public class ConsumerDemo {

public static void main(String[] args) {
	// get方法需要3个参数
	// 1. money : 钱数
	// 2. Consumer<String> con--->函数式的接口
	// 接口作为参数传递,实际应该传递的是接口的实现类
	Consumer<String> con = (t)->System.out.println("买了"+t);
	get(800,con,"大宝剑");
	get(800,con,"小兔兔");
}

// Consumer<String> con : 一个消费型的接口,作用就是能对一个String类型的数据
// 进行消费
public static void get(int money,Consumer<String> con,String str) {
	System.out.print("今天花了"+money);
	con.accept(str);
}

}

2.4供给型接口
Supplier : 供给型接口
方法 : T get() : 不需要参数,直接给出一个结果

需求: 创建一个集合ArrayList ,集合中存储的元素个数,由参数决定,集合中存储的整数内容不确定(先设计为30-80之间的随机整数),定义方法,返回这个集合

代码
package com.zgjy.interfaceDemo;
import java.util.ArrayList;
import java.util.Random;
import java.util.function.Supplier;
public class SupplierDemo {
public static void main(String[] args) {
// 需要一个Supplier sup的实现类
// 30-80之间的随机整数
Supplier sup = ()->new Random().nextInt(51)+30;

	Supplier<Integer> sup1 = new Supplier<Integer>() {

		@Override
		public Integer get() {
			// TODO Auto-generated method stub
			return new Random().nextInt(51)+30;
		}	
	};
	ArrayList<Integer> list = getArr(3,sup1);
	System.out.println(list);
}

public static ArrayList<Integer> getArr(int n,Supplier<Integer> sup){
	ArrayList<Integer> list = new ArrayList<>();
	for(int i = 0 ; i < n ; i++) {
		list.add(sup.get());
	}
	return list;
}

}

2.5函数型接口
Function<T,R> : 函数式接口
方法 : R apply(T t) : 提供参数类型t,返回结果类型R

要求: 给你一个int类型参数,返回一个int类型数据,返回的数据,可能每次方法调用可能不一致

代码
package com.zgjy.interfaceDemo;
import java.util.function.Function;
public class FunctionDemo {
public static void main(String[] args) {
// 匿名内部类对象实现Function<Integer,Integer> fun函数式接口
Function<Integer,Integer> fun = new Function<Integer,Integer>(){

		@Override
		public Integer apply(Integer t) {
			// TODO Auto-generated method stub
			return t*2;
		}
	};
	
	int result = get(5,fun);
	System.out.println(result);// 10
	
	// 使用lambda表达式实现Function<Integer,Integer> fun函数式接口
	Function<Integer,Integer> fun1 = x -> {
		x = x * 2 ;
		return x +3;
	};	
	int result1 = get(5,fun1);
	System.out.println(result1);// 13
}

// R apply(T t)
public static int get(int x , Function<Integer,Integer> fun) {
	return fun.apply(x);
}

}

2.6断言型接口
Predicate : 断言型接口,一般用于做数据的筛选
方法 : boolean test(T t) : 提供一个数据t,将t是否符合规则结果输出

要求: 创建一个集合ArrayList,向集合中添加数据,方法功能 : 将集合中符合某种规则的数据筛选到新的集合中,返回新的集合

代码
package com.zgjy.interfaceDemo;
import java.util.ArrayList;
import java.util.function.Predicate;
public class PerdictedDemo {
public static void main(String[] args) {
ArrayList list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
list.add(6);
list.add(7);

	// 匿名对象实现Predicate<Integer> pre
	Predicate<Integer> pre = new Predicate<Integer>() {

		@Override
		public boolean test(Integer t) {// 可以被2整除的数据
			if(t % 2 == 0) {
				return true;
			}else{
				return false;
			}	
		}
	};
	ArrayList<Integer> list1 = returnArr(list,pre);
	System.out.println(list1);
	
	// Lambda表达式进行数据筛选
	// 可以被3整除的
	Predicate<Integer> pre1 = x -> x % 3 == 0 ;
	
	Predicate<Integer> pre2 = x -> {
		if(x % 4 == 0) {
			return true;
		}else{
			return false;
		}	
	};
	
	// 筛选被3整除的数据
	ArrayList<Integer> list2 = returnArr(list,pre1);
	System.out.println(list2);
	// 筛选被4整除的数据
	ArrayList<Integer> list3 = returnArr(list,pre2);
	System.out.println(list3);
}

/*
 * 要求: 创建一个集合ArrayList<Integer>,向集合中添加数据
 * 方法功能 : 将集合中符合某种规则的数据筛选到新的集合中,返回新的集合
 * 
 * */

// Predicate pre 参数 : 传递的实际上是对于一个Integer类型参数的判断方式
public static ArrayList returnArr(ArrayList arr, Predicate pre){
ArrayList list = new ArrayList<>();
// 将集合中的每一个元素获取到,验证每一个元素是否符合规则
// 符合 : 添加到新的集合中
// 不符合 : 不添加,继续进行下一个元素的验证
for(Integer i : arr) {
if(pre.test(i)) {// 符合
list.add(i);
}
}
return list;
}
}

  1. Streaming表达式
    Stream接口 : 是一个流资源,主要功能是能进行数据的筛选和遍历
    Stream中的比较常用的方法:
  2. filter(Predicate<? super T> predicate) : 功能是能按照参数的断言型接口进行数据的筛选,返回值类型Stream的实现类
    参数 : 是一个断言型的接口,方法实际调用需要传递接口的实现类(可以使用Lambda表达式)
  3. forEach(Consumer<? super T> action) : 功能进行数据的遍历
    参数 : 是一个消费型的接口,参数的作用,消费(操作给出的数据),循环操作

注意 : 因为Collection单列集合的顶层父接口,从JDK1.8版本开始,添加了一个方法,
stream() : 能获取到一个Stream的实现类对象,返回值类型Stream类型

要求 : 创建一个集合ArrayList , 集合中存储的是姓名, 将姓张的,并且名字带有3个字的数据输出出来

代码
package com.zgjy.stream;
import java.util.ArrayList;
public class StreamDemo {
public static void main(String[] args) {
ArrayList list = new ArrayList<>();
list.add(“张三丰”);
list.add(“李24”);
list.add(“张三”);
list.add(“张无忌”);
list.add(“张二麻子”);
list.add(“周芷若”);
getName(list);
System.out.println("---------");
streamGetName(list);
}

/*
 * 要求 : 创建一个集合ArrayList<String> , 
 * 集合中存储的是姓名, 将姓张的,并且名字带有3个字的数据输出出来
 * */

// 1. 使用以前学习的方法
public static void getName(ArrayList<String> list) {
	// 1. 获取到集合中的每一个元素
	for( String name : list) {
		// 2. 判断名字是否符合规则
		// 1) 姓张: 名字字符串的第一个字符是张字
		// 2) 名字长度3个字 : 名字的字符串长度为3
		if(name.startsWith("张") && name.length() == 3) {
			System.out.println(name);
		}
	}	
}

// 2. 使用Stream进行数据的筛选和遍历
public static void streamGetName(ArrayList<String> list) {
	// 1. 获取到一个Stream的实现类
	// 1) list.stream() ---> 获取到Stream的一个实现类对象
	// 2) 链式调用filter(predicate)---> 使用断言型接口的实现方式
	//   boolean test(T t)
	// 3) 将符合条件的数据循环的输出,使用Stream中的forEach
	// forEach(Consumer)
	//  apply(T t)
	list.stream().filter(x->x.startsWith("张"))
	.filter(x->x.length()==3).forEach(x->System.out.println(x));	
}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值