方法引用
当lambda体的实现,是通过调用其他方法实现的,可以通过方法引用的方式实现简化lambda表达式
所以,方法引用时lambda表达式的另外一种表现形式。
BiPredicate<String,String> pre = (x,y)-> x.equals(y);可以简化----》
BiPredicate<String,String> pre = String::equals;
语法格式为(::)
可以简化的情况:
1,lambda体的实现是通过调用了另外一个方法实现的
2,内部所引用的方法的返回值是与lambda的返回值保持一致
调用方法
对象::成员方法名
//对象::成员方法名
public static void test1(){
List<Integer> list = List.of(1,2,3,4,5);
list.forEach(x->{
System.out.println(x);
});
PrintStream ps = System.out;
list.forEach(x->{
ps.println(x);
});
/*
分析:
1)lambda体的实现是否是通过调用了另外一个方法实现的 --> √
2)内部所引用方法的返回值是否与lambda的返回值保持一致 --> √
*/
list.forEach(ps::println);
list.forEach(System.out::println);
}
类名::静态方法名
//类名::静态方法名
public static void test2(){
//求两个数中最大的值
//BiFunction<Integer,Integer,Integer> function = (x,y)-> Math.max(x,y);
/*
分析:
1)lambda体的实现是否是通过调用了另外一个方法实现的 --> √
2)内部所引用方法的返回值是否与lambda的返回值保持一致 --> √
*/
BiFunction<Integer,Integer,Integer> function = Math::max;
System.out.println(function.apply(100,101));;
//Comparator<Integer> com = (x,y) -> {return Integer.compare(x,y);};
/*
分析:
1)lambda体的实现是否是通过调用了另外一个方法实现的 --> √
2)内部所引用方法的返回值是否与lambda的返回值保持一致 --> √
*/
Comparator<Integer> com = Integer::compareTo;
System.out.println(com.compare(18,18));;
}
类名::成员方法名
//类名::成员方法名
public static void test3(){
//BiPredicate<String,String> pre = (x,y)-> x.equals(y);
/*
分析: 通过类名::成员方法名 简化lanbda结构
1)lambda体的实现是否是通过调用了另外一个方法实现的 --> √
2) 内部所引用方法的返回值与lambda的返回值相同
lambda参数列表的第一个参数作为内部引用成员方法的对象存在
lmabda参数列表的第二个参数开始(如果有的话)作为内部引用方法的参数列表
*/
BiPredicate<String,String> pre = String::equals;
System.out.println(pre.test("张三","张三封"));;
}
Stream流
根据数据源所产生的元素序列
数据源:集合,数组——>侧重点在于数据的存储
stream流:关注与数据的计算
注意:
1.流本身不能存储数据
2.流不能修改 数据源中的数据
3.流是一次性的流,流式操作的每一步都会返回一个持有一个结果的新流
4.流是延迟执行|惰性加载:当不进行终止行为的时候,不会执行流式中间操作
流操作的过程:
1.获取|创建一个stream流
2.流式的中间操作
3.终止行为(返回的结果不在是一个流)
创建流的几种方式:
1.Collection--> stream
2.Arrays.stream(array)
3.Stream.of(数据1,数据2,数据3...) 或者 Stream.of(数组)
public static void main(String[] args) {
//1.Collection--> stream
List<Integer> list = new ArrayList<>();
//顺序流
Stream<Integer> stream = list.stream();
//并行流
Stream<Integer> stream2 = list.parallelStream();
System.out.println(stream2);
//2) Arrays.stream(array)
Stream stream3 = Arrays.stream(new String[]{"1"});
System.out.println(stream3);
//3)Stream.of(数据1,数据2,数据3...)
Stream stream4 = Stream.of("a","b");
stream4.forEach(System.out::println);
//4)Stream.of(数组)
Stream stream5 = Stream.of(new String[]{"abc","bcd"});
stream5.forEach(System.out::println);
}
流式的中间操作
1.筛选和切片
1.filter -- 接收一个lambda,从流中排除某些元素
2.limit -- 截断流,使流的元素不超过给定的数量
3.skip -- 跳过元素,返回一个扔掉了给定数量的流,若流中的元素比给定数量小,那么就返回一个空流
4.distinct -- 筛选,通过流的生产元素的hasCode()和equals()去除重复元素
2.排序
sorted(Comparable)-自然排序
sorted(Comparator)-定制排序
static List<Employee> emps = Arrays.asList(
new Employee(102,"张三", 18, 3333.33),
new Employee(101,"李四", 38, 4444.44),
new Employee(104,"王五", 50, 5555.55),
new Employee(104,"王五", 50, 5555.55),
new Employee(103,"赵六", 16, 6666.66),
new Employee(105,"田七", 28, 7777.77)
);
public static void main(String[] args) {
//1.获取流
Stream<Employee> stream = emps.stream();
//2.中间操作
Stream<Employee> stream1 = stream
.filter(e->{
//System.out.println("--中间过滤操作--->"+e);
return e.getAge()>=18;
})
.distinct() //去重
//.limit(3)
//.skip(1)
//.sorted(); //默认根据内部比较器
.sorted((x,y)->Double.compare(y.getPrice(), x.getPrice()));
//3.终止行为
stream1.forEach(System.out::println);
}
3.映射
map : 将stream操作的每一个元素都作用与实参传递的函数,映射一个结果,返回操作结果的流
flatMap : 将stream操作的每一个元素都作用与实参传递的函数,映射一个结果,结果必须为一个流,最终返回所有结果流结合以后的一个流
static List<Employee> emps = Arrays.asList(
new Employee(102,"张三", 18, 3333.33),
new Employee(101,"李四", 38, 4444.44),
new Employee(104,"王五", 50, 5555.55),
new Employee(104,"王五", 50, 5555.55),
new Employee(103,"赵六", 16, 6666.66),
new Employee(105,"田七", 28, 7777.77)
);
public static void main(String[] args) {
//1.获取流
Stream<Employee> stream = emps.stream();
//2.中间操作
//1) 获取员工姓名的流
Stream<String> stream1 = stream
.map(employee -> employee.getName())
.distinct();
List<String> list = List.of("aaa","bbb","ccc");
Stream<Character> stream2 = list.stream()
//.map(Class003_map::getCharacterStream); //[[a,a,a],[b,b,b],[c,c,c]]
.flatMap(Class003_map::getCharacterStream); //[a,a,a,b,b,b,c,c,c]
//3.终止行为
stream1.forEach(System.out::println);
//流中操作流
*/
/*stream2.forEach(s->{
s.forEach(System.out::println);
});*//*
stream2.forEach(System.out::println);
}
//测试 : 接收一个字符串,返回每一个字符串中所有字符的流
public static Stream<Character> getCharacterStream(String str){
//1.转为字符数组
List<Character> ls = new ArrayList<>();
for(char ch : str.toCharArray()){
ls.add(ch);
}
return ls.stream();
}
流的终止行为
查找和匹配
收集 collect()
public class Class004_Stream {
static List<Employee> emps = Arrays.asList(
new Employee(102,"张三", 18, 3333.33),
new Employee(101,"李四", 38, 4444.44),
new Employee(104,"王五", 50, 5555.55),
new Employee(104,"王五", 50, 5555.55),
new Employee(103,"赵六", 16, 6666.66),
new Employee(105,"田七", 28, 7777.77)
);
public static void main(String[] args) {
//获取流
Stream<Employee> stream = emps.stream();
//终止行为
System.out.println(stream.allMatch(e->e.getAge()>=18));
// 需求:找到员工工资最高的员工信息
//1)按照工资做降序排序
//找到第一个
Optional<Employee> op = emps.stream().sorted((x, y)->Double.compare(y.getPrice(),x.getPrice())).findFirst();
System.out.println(op.get());
//findAny-返回当前流中的任意元素
System.out.println(emps.parallelStream().findAny().get());
System.out.println(emps.stream().parallel().findAny().get());
//count-返回流中元素的总个数
System.out.println(emps.stream().filter(e->e.getPrice()>=5000).distinct().count());
//2)max()
System.out.println(emps.stream().max((x,y)->Double.compare(x.getPrice(),y.getPrice())).get());;
//找到薪资最高的薪资值
System.out.println(emps.stream().map(Employee::getPrice).max(Double::compareTo).get());;
需求:获取当前公司所有员工的姓名添加到集合中
//toList()
List<String> list = emps.stream()
.map(Employee::getName)
.collect(Collectors.toList());
list.forEach(System.out::println);
//toSet()
Set<Double> set = emps.stream()
.map(Employee::getPrice)
.collect(Collectors.toSet());
set.forEach(System.out::println);
//toMap()
System.out.println(emps.stream().distinct().collect(Collectors.toMap(Employee::getId,Employee::getName)));;
工资总和
System.out.println(emps.stream().collect(Collectors.summingDouble(Employee::getPrice)));;
}
}