目录
Lambda表达式
方法引用
方法引用:若Lambda 体中的内容有方法已经实现了,我们可以使用“方法引用”(可以理解为方法引用是Lambda 表达式的另一种表现形式)
主要有三种语法格式:
对象 :: 实例方法名
类 :: 静态方法名
类 :: 实例方法名
注意:
1、Lambda 体中调用方法的参数列表与返回值类型,要与函数式接口中抽象方法的返回值类型保持一致
2、若Lambda参数列表中的第一参数是实例方法的调用者,而第二个参数是实例方法的惨数时,可以使用ClassName :: method
// 对象::实例方法名 例:
public void test(){
PrinStream ps= System.out;
Commsumer<String> con =(x) -> ps.println(x); //Lambda 表达式
PrintStream ps1 =System.out;
Consumer<String> con1 =ps::println; //Lambda 体中的内容有方法已经实现了,我们可以使用“方法引用”
Consumer<String> con2 =System.out::println;
con2.appect("dsda")
}
// 类::静态方法名 例:
public void test2(){
Comparator<Integer> com =(x,y) -> Integer.compare(x,y);
Comparator<Integer> com1= Integer::compare;
}
//类::实例方法名
public void test3(){
BiPredicate<String,String> bp =(x,y)->x.equals(y);
BiPredicate<String,String> bp1 = String::equals;
}
构造器引用
格式:
ClassName :: new
注意:需要调用的构造器的参数列表要与函数式接口中抽象方法的参数列表保持一致
Supplier<Employee> sup = ()-> new Employee();
Supplier<Employee> sup1 = Employee :: new; //调用哪个构造器取决于Supplier函数的参数
Function<Interger,Employee> fun = (x) -> new Employee(x);
Function<Interger,Employee> fun1 = Employee :: new; //调用哪个构造器取决于Function函数的参数
数组引用:
格式: Type :: new;
Function<Integer,String[]> fun = (x)-> new String[x];
String[] strs= fun.apply(10);
Function<Integer,String[]> fun = String[]::new;
String[] strs= fun.apply(15);
流是什么:
是数据渠道,用于操作数据源(集合、数组等)所生产的元素序列。
“集合讲的是数据,流讲的是计算!”
注意:
1、Stream自己不会存储元素
2、Stream不会改变源对象。相反,他们会返回一个持有结果的新Stream。
3、Sream操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。
Steam的操作三个步骤
创建Stream
一个数据源(如集合、数组),获取一个流
中间操作
一个中间操作链,对数据源的数据进行处理
终止操作
一个终止操作,执行中间操作链,并产生结果
流的使用
//1.可以通过Collection系列集合提供的steam()或parallelStram()
List<String> list = new ArrayList<>();
Stream<String> stream1 = list.stream;
//2.通过Arrays中的静态方法stream()获取数组流
Employee[] emps = new Employee[10];
Stream<Employee> stream2 = Arrays.stream(emps);
//3.通过Stream类中的静态方法of()
Stream<String> stream3 = Stream.of("aa","bb","cc");
//4.创建无限流
Stream<Integer> stream4 =Stream.iterate(0,(x)->x+2);
//迭代
stream.forEach(System.out::println);
//生成
Stream.generate(()->Math.random()),limit(5).forEach(System.out::println)
多个中间操作可以连接起来形成一个流水线,除非流水线上触发终止操作,否则中间操作不会执行任何的处理!而在终止操作时一次性全部处理,称为“惰性求值”
//筛选与切片
//filter--接受Lambda,从流中排除某些元素。
//limit--截断流,使其元素不超过给定数量。
//skip(n)--跳过元素,返回一个扔掉前n个元素的流。若流汇总元素不足n个,则返回一个空流,与limit(n)互补
//distinct--筛选,通过流产生元素的hashCode()和equals()去除重复元素
//中间操作 不会执行任何的操作的
Stream<Employee> s =employees.stream()
.filter((e)-> e.getAge()>35);
//终止操作 只有终止操作之后才会一次性的执行全部任务,即“惰性求值” //内部迭代
s.forEach(System.out::println);
//外部迭代
Iterator<Employee> it = employees.iterator();
while(it.hasNext()){
System.out.println(it.next);
}
//映射
//map--接收Lambda,将元素转换成为其他形式或提取信息。接受一个函数作为参数,
该函数会被应用到每个元素上,并将其映射成一个新的元素。flatMap--接受一个函
数作为参数,将流中的每一个值都换成另一个流,然后把所有流连接成一个流
public void test(){
List<String> list = Arrays.asList("aaa","bbb","ccc","ddd","eee")
list.stream()
.map((str)-> str.toUpperCase())
.forEacch(System.out::println);
employee.stream()
.map(Employee::getName)
.forEach(System.out::println);
System.out.println("---------------------------------------");
Stream<String<Character>> stream =list.stream()
.map(Tests::filerCahacter);
stream.forEach((sm)->{
sm.forEach(System.out::println);
})
System.out.println("---------------------------------------");
Stream<Character> as = list.stream().flatmap(Tests::filerCahacter);
}
//查找与匹配
allMatch--检查是否匹配所有元素
anyMatch--检查是否至少匹配一个元素
noneMath--检查是否没有匹配一个元素
findFirst--检查是否至少匹配所有元素
findAny--返回第一个元素
count--返回流中元素的总个数
max--返回流中最大数
min--返回流中最小数
boolean b=employees.stream().allMatch((e)->e.getStatus.equals(Status.BUSY));
归约
reduce(T identity,BinaryOperator)/reduce(BinaryOperator) -可以将流中元素反复结合起来,得到一个值
@Test
public void test(){
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8);
//将起始0先作为x的第一个元素,从流中取得作为y
list.stream().reduce(0,(x+y)-> x+y);
//可能为空的封装到Opetional中
Optional<Double> op = employees.stream()
.map(Employee::getSalary)
.reduce(Double::sum);
}
收集:
Collector接口中方法的实现决定了如何对流执行收集操作(如收集到List、Set、Map)。但是Collectors实用类提供了很多静态方法,可以方便地常见收集器实例。具体方法与实例如下:
List<String> list =employees.stream()
.map(Employee::getName)
.collect(Collectors.tolist());
//平均值
Double a =employees.stream()
.collect(Collectors.averagingDouble(Employee::getSalary));
//分组
Map<Status,list<Employee>> map =employees.stream()
.collect(Collectors.groupingBy(Employee::getStatus));
//多级分组
Map<Status,Map<String,list<Employee>>> map = employees.stream
.collect(Collectots.groupingBy(Employee::getStatus,Collecctors.groupingBy((e)->{
if(((Employee)e).getAge()<=12){return "ds"}}));
//分区
Map<Boolean,List<Employee>> map = employee.stream()
.collect(Collectors.partitioningBy((e)->e.getAge()>18));
使用例题:
1.给定一个数字列表,如返回一个每个数的平方构成列表呢:
输入[1,3,5],输出[1,9,25]
public void test(){
Integer[] nums =new Integer[]{1,3,5};
Arrays.stream(nums)
.map((x)-> x*x)
.forEach(Systemou::println);
}
本人笔记
资料来源:尚学堂