第十四章 lambda表达式与流处理

14.1lambda表达式

lambda表达式可以用非常少的代码实现抽象方法。不能独立执行,必须是实现函数式接口,并返回一个函数式接口的对象。

()->结果表达式
参数->结果表达式
(参数1,参数2,...,参数n)->结果表达式
package fourteen;
	interface SayhHi{
		String say();//抽象方法接口
	}
 
 
public class NoParamDemo {
	public static void main(String[] args) {
		//无参数
		//利用匿名内部类补全方法体
		 SayhHi sh1 = new SayhHi() {
			 public String say() {
				 return "这是匿名内部类";
			 }
		 };
		 System.out.print(sh1.say());
	}
 
}

使用表达式表达

 System.out.print(sh1.say());
		 //利用lambda表达式补全方法体
		 SayhHi sh2 =() -> {
			 return "这是lambda表达式";
		 };
		 System.out.println(sh2.say());
		 
	}
 
}
 

第十四章 lambda表达式与流处理_第1张图片

有参数

使用表达式

package fourteen;
interface AddInt{
	 int add(int a,int b);//抽象方法接口
}
 
public class Prama {
 
	public static void main(String[] args) {
		//有参数
		//利用匿名内部类补全方法体
		AddInt ai1 = new AddInt() {
			 public int add(int a,int b){
				 return a+b;
			 }
		 };
		 System.out.println("匿名内部类:"  + ai1.add(3, 5));
		 //利用lambda表达式补全方法体
		 AddInt ai2=( a, b) -> {
			 return a+b ;
		 };
		 System.out.println("lambda表达式:"+ai2.add(3, 5));
		 
	}
 
}

第十四章 lambda表达式与流处理_第2张图片

例题

package fourteen;
interface CheckGrade {
	String check(int grade); // 查询成绩结果
}
 
public class GradeDemo {
	public static void main(String[] args) {
		CheckGrade g = (n) -> { // lambda实现代码块
			if (n >= 90 && n <= 100) { // 如果成绩在90-100
				return "成绩为优"; // 输出成绩为优
			} else if (n >= 80 && n < 90) { // 如果成绩在80-89
				return "成绩为良"; // 输出成绩为良
			} else if (n >= 60 && n < 80) { // 如果成绩在60-79
				return "成绩为中"; // 输出成绩为中
			} else if (n >= 0 && n < 60) { // 如果成绩小于60
				return "成绩为差"; // 输出成绩为差
			} else { // 其他数字不是有效成绩
				return "成绩无效"; // 输出成绩无效
			}
		}; // 不要丢掉lambda语句后的分号
		System.out.println(g.check(89)); // 输出查询结果
	}
}

第十四章 lambda表达式与流处理_第3张图片

//使用方法的引用补全方法体

双冒号::

static int add(int x, int y) {//方法的引用,这是方法体的方法

return x+y;

}

static int add(int x, int y) {//方法的引用,这是方法体的方法

return x+y;

}

完整代码

package fourteen;
interface AddInt{
	 int add(int a,int b);//抽象方法接口
}
 
public class Prama {
	static int add(int x, int y) {//方法的引用,这是方法体的方法
		//对象也可以找到这个方法体,非静态
		return x+y;
	}
	
 
	public static void main(String[] args) {
		//有参数
		//利用匿名内部类补全方法体
		AddInt ai1 = new AddInt() {
			 public int add(int a,int b){
				 return a+b;
			 }
		 };
		 System.out.println("匿名内部类:"  + ai1.add(3, 5));
		 //利用lambda表达式补全方法体
		 AddInt ai2=( a, b) -> {
			 return a+b ;
		 };
		 System.out.println("lambda表达式:"+ai2.add(3, 5));
		 //使用方法的引用补全方法体
		 AddInt ai3 = Prama::add;//找到类,找到方法体
		 System.out.println("方法体:"+ai3.add(3, 5));
		 
	}
 
}

第十四章 lambda表达式与流处理_第4张图片

例14.8

package fourteen;
 
import java.text.SimpleDateFormat;
import java.util.Date;
interface InstanceMethodInterface {                    // 创建测试接口
    String method(Date date);                           // 带参数的抽象方法
}
public class InstanceMethodDemo {
    public String format(Date date) {                  // 格式化方法
        // 创建日期格式化对象,并指定日期格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(date);                       // 返回格式化结果
    }
 
    public static void main(String[] args) {
        // 创建类对象
        InstanceMethodDemo demo = new InstanceMethodDemo();
        // 引用类对象的方法
        InstanceMethodInterface im = demo::format;
        Date date = new Date();                       // 创建日期对象
        System.out.println("默认格式:" + date);     // 输出日期对象默认格式
        // 输出经过接口方法处理过的格式
        System.out.println("接口输出的格式:" + im.method(date));
    }
}//14.8
 

第十四章 lambda表达式与流处理_第5张图片

//调用构造器


package fourteen;
	interface ConIn{
		ConDemo action();//创建接口,正好是这个类的构造器类型,抽象方法
		
	}
public class ConDemo {
	//使用无参的构造方法补全方法体
	public ConDemo() {//构造方法要写小括号
		System.out.println("无参构造方法");//构造方法
	}
	public ConDemo(int a) {//构造方法要写小括号
		System.out.println("有参构造方法");//构造方法
	}
	public static void main(String args[]) {
		ConIn ci1 = ConDemo:: new;//new一个对象
		ci1.action();//调用action方法
		//使用有参数的方法来补全方法体
		//ConDemo action(int a);
		//ConIn ci1 = ConDemo:: new;//new一个对象
		//ci1.action(5);//调用action方法
	}
	
}
 

 stream接口

package fourteen;
 
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
 
public class StreamDemo {
	
	public static void main(String[] args) {
	List list=Employee.getEmpList();//从employee表拿到list表中的员工表
	Stream stream = list.stream();//调用list方法将表转换成流
	//筛选年龄>30岁的员工
	stream=stream.filter(sx-> sx.getAge()>30);//写条件,sx属于临时变量
	//限制条数
	stream = stream.limit(2);
	List result = stream.collect(Collectors.toList());//转成List链表
	for (Employee sx : result) {//for循环输出结果
		System.out.println(sx);
		
	}
	}
 
}

第十四章 lambda表达式与流处理_第6张图片

数据分组

package fourteen;
 
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
 
public class GroupDemo {
 
	public static void main(String[] args) {
		// 分组
		List list=Employee.getEmpList();//从employee表拿到list表中的员工表
		Stream stream = list.stream();//调用list方法将表转换成员工流
		Map> map = //创建map集合存入,String代指dept,list链表指代map集合的value
		stream.collect(Collectors.groupingBy(Employee::getDept));//利用流调用collect方法,分组方法,传入方法
		Set depts = map.keySet();//获取map集合中的部门表
		for(String dept:depts){//for循环一个部门,depts代指部门
			System.out.println(dept+"员工信息如下:");//输出信息
			List temp = map.get(dept);//分组列表输出
			for(Employee g : temp){//temp是临时变量
				System.out.println(g);//
			}
			System.out.println();
		}
		
		
 
	}
 
}

第十四章 lambda表达式与流处理_第7张图片

14.3流处理

流处理有点类似数据库的SQL语句,可以执行非常复杂的过滤、映射、查找和收集功能,并且代码量很少。唯一的缺点是代码可读性不高,如果开发者基础不好,可能会看不懂流API所表达的含义。

import java.util.ArrayList;
import java.util.List;

public class Employee {
	private String name;
	private int age;
	private double salary;
	private String sex;
	private String dept;
	public Employee(String name, int age, double salary, String sex, String dept) {
		super();
		this.name = name;
		this.age = age;
		this.salary = salary;
		this.sex = sex;
		this.dept = dept;
	}
	@Override
	public String toString() {
		return "Employee [name=" + name + ", age=" + age + ", salary=" + salary + ", sex=" + sex + ", dept=" + dept
				+ "]";
	}
	public String getName() {
		return name;
	}
	public int getAge() {
		return age;
	}
	public double getSalary() {
		return salary;
	}
	public String getSex() {
		return sex;
	}
	public String getDept() {
		return dept;
	}
	static ListgetEmpList(){
		List list=new ArrayList();
		list.add(new Employee("老张",40,9000,"男","运营部"));	
		list.add(new Employee("小刘",24,5000,"女","开发部"));	
		list.add(new Employee("大刚",32,7500,"男","销售部"));	
		list.add(new Employee("翠花",28,5500,"女","销售部"));	
		list.add(new Employee("小马",21,3000,"男","开发部"));	
		list.add(new Employee("老王",35,6000,"女","人事部"));
		list.add(new Employee("小王",21,3000,"女","人事部"));	
		
		
				
				return list;
	}

}

14.3.1stream接口简介

流处理的接口都定义在 java.uil.stream 包下。BaseStream接口是最基础的接口,但最常用的是BaseStream 接口的一个子接口——Stream 接口,基本上绝大多数的流处理都是在Stream接口上实现的。Stream 接口是泛型接口,所以流中操作的元素可以是任何类的对象。

第十四章 lambda表达式与流处理_第8张图片

Collection 接口新增两个可以获取流对象的方法。第一个方法最常用,可以获取集合的顺序流,方法如下:

Stream stream();

第二个方法可以获取集合的并行流,方法如下:

Stream parallelstream();

因为所有集合类都是Collection 接口的子类,如ArrayList类、HashSet类等,所以这些类都可以进行流处理。

List list = new ArrayList();
//创建集合
Stream s = list.stream();
//获取集合流对象

14.3.2 optional类

Optional 类像是一个容器,可以保存任何对象,并且针对 NullPointerException 空指针异常做了代化,保证Optional类保存的值不会是null。因此,Optional类是针对“对象可能是null也可能不是m的场景为开发者提供了优质的解决方案,减少了烦琐的异常处理。
Optional 类是用 final修饰的,所以不能有子类。Optional类是带有泛型的类,所以该类可以保存任何对象的值。
从Optional类的声明代码中就可以看出这些特性,JDK中的部分代码如下:

public final class Optional{
private final T value;
…}
//省略其他代码

列14.15

import java.util.Optional;
public class OptionalDemo{
public static void main(String[] args) {
Optional strValue = Optional.of("Hello");//创建有值对象

boolean haveValueFlag = strValue.isPresent();//判断对象中的值是不是空的

System.out.println("strValue 对象是否有值:"+ haveValueFlag);
if (haveValueFlag){    //如果不是空的

String str = strValue.get();//获取对象中的值
System.out.println("strValue 对象的值是:"+ str);
}

Optional noValue = Optional.empty();//创建空值对象
boolean noValueFlag = noValue.isPresent();//判断对象中的值是不是空的


System.out.println("noValue 对象是否有值:"+noValueFlag);
if (noValueFlag){//如果不是空的

String str = noValue.get();//获取对象中的值

System.out.println("noValue 对象的值是:"+str);
}else{//如果是空的

String str = noValue.orElse("使用默认值");//使用默认值

System.out.println("noValue 对象的值是:"+ str);
}}}

第十四章 lambda表达式与流处理_第9张图片

14.3.3collectors类

Collectors 类为收集器类,该类实现了java.util.Collector 接口,可以将Stream流对象进行各种各样的封装、归集、分组等操作。同时,Collectors 类还提供了很多实用的数据加工方法,

第十四章 lambda表达式与流处理_第10张图片

第十四章 lambda表达式与流处理_第11张图片

14.3.4数据过滤

数据过滤就是在杂乱的数据中筛选出需要的数据,类似SQL语句中的WHERE关键字,给出一定的条件,将符合条件的数据过滤并展示出来。

1.filter()方法
filter()方法是Stream 接口提供的过滤方法。该方法可以将lambda表达式作为参数,然后按照lambda表达式的逻辑过滤流中的元素。过滤出想要的流元素后,还需使用Stream 提供的collect()方法按照指定方法重新封装。

14.16

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util. stream.Stream;
public class FilterOddDemo{
	static void printeach(String message, List list){//输出集合元素
		System.out.print(message);//输出文字信息
		list.stream().forEach(n->{//使用foeEach方法遍历集合并打印元素
			System.out.print(n +"");
		});
			System.out.println(); //换行
			}
	public static void main(String[]args) {
	List list = new ArrayList<>();//创建空数组
		for (int i= 1;i<= 10;i++){//从1循环到10
			list.add(i);//给集合赋值
		}

		

	printeach("集合原有元素:",list);//输出集合元素
	Stream stream = list.stream();//获取集合流对象
//将集合中的所有奇数过滤出来,把过滤结果重新赋值给流对象


//使用forEach方法遍历集合并打印元素

	stream = stream.filter(n -> n % 2 == 1);
//将流对象重新封装成一个List集合
	
	List result = stream.collect(Collectors.toList());
	printeach("过滤之后的集合元素:",result);//输出集合元素
	}
}

第十四章 lambda表达式与流处理_第12张图片

14.17

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class FilerDemo {
public static void main(String[]args){
	List list = Employee.getEmpList();//获取公共类的测试数据
	Stream stream = list.stream();//获取集合流对象
	stream = stream.filter(people -> people.getAge()> 30);//将年龄大于30岁的员工过滤出来
	List result = stream.collect(Collectors.toList());//将流对象重新封装成一个 List 集合
	for (Employee emp : result){//遍历结果集
		System.out.println(emp);//输出员工对象信息
	}
}
}

第十四章 lambda表达式与流处理_第13张图片

2. distinct()方法
distinct()方法是Stream 接口提供的过滤方法。该方法可以去除流中的重复元素,效果与SOL中的DISTINCT关键字一样。

14.18

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util. stream.Stream;
	public class DistinctDemo{
		static void printeach(String message, List list) {//输出集合元素
			System.out.print(message);	//输出文字信息	
			
			list.stream().forEach(n->{//使用forEach方法遍历集合并打印元素
				System.out.print(n +"");
			});
				System.out.println();//换行
		}



		public static void main(String[]args){
			List list = new ArrayList();//创建集合
			list.add(1);//添加元素
			list.add(2);
			list.add(2);
			list.add(3);
			list.add(3);
			printeach("去重前:",list);//打印集合元素
			Stream stream = list.stream();//获取集合流对象
			stream = stream.distinct();//取出流中的重复元素
			List reslut = stream.collect(Collectors.toList());//将流对象重新封装成一个List集合
			printeach("去重后:",reslut);//打印集合元素

		}
	}




第十四章 lambda表达式与流处理_第14张图片

3. limit()方法
limit()方法是Stream 接口提供的方法,该方法可以获取流中前N个元素

14.19

import java.util.List;
import java.util. stream.Collectors;
import java.util. stream.Stream;

	public class LimitDemo{
		public static void main(String[]args) {
			List list = Employee.getEmpList();//获取公共类的测试数据
			Stream stream = list.stream();//获取集合流对象
			stream = stream.filter(people ->"女".equals(people.getSex()));//将所有女员工过滤出来
			stream = stream.limit(2);//取出前两位
			List result = stream.collect(Collectors.toList());//将流对象重新封装成一个 List 集合
			for (Employee emp : result) {//遍历结果集
			System.out.println(emp);	//输出员工对象信息
			}
		}
	}



第十四章 lambda表达式与流处理_第15张图片

4.skip()方法
skip0方法是Stream接口提供的方法,该方法可以忽略流中的前N个元素。

14.20

import java.util.List;
import java.util. stream.Collectors;
import java.util. stream.Stream;
public class SkipDemo{
public static void main(String[]args) {
List list = Employee.getEmpList();//获取公共类的测试数据
Stream stream = list.stream();//获取集合流对象
stream = stream.filter(people ->"男".equals(people.getSex()));//将所有男员工过滤出来
stream = stream.skip(2);//跳过前两位
List result = stream.collect(Collectors.toList());//将流对象重新封装成一个List集合

for (Employee emp : result){
System.out.println(emp);
}
}
}

第十四章 lambda表达式与流处理_第16张图片

14.3.5 数据映射
数据的映射和过滤概念不同:过滤是在流中找到符合条件的元素,映射是在流中获得具体的数强.Stream 接口提供了map()方法用来实现数据映射,map()方法会按照参数中的函数逻辑获取新的对象,新的流对象中元素类型可能与旧流对象元素类型不相同。

你可能感兴趣的:(python,开发语言)