基础语法
()->
()->{***;}
例子:
()->{}
()->"abc"
()->{return "MMM";}
(String s)->s.length()
(Apple a)->a.getWeight() >100
(int x,int y)->{System.out.println(inventory);}
()->44
(Apple a1,Apple a2)->a1.getWeight(),compareTo(a2.getWeight())
(Apple a)->a.getWeight() 等效于 Apple::getWeight
(str,i)->str.substring(i) 等效于String::substring
(String s)->System.out.println(s) 等效于System.out::println
List inventory =
Arrays.asList(new Apple(80, "green"), new Apple(155, "green"), new Apple(120, "red"));
inventory.sort((Apple a, Apple b) -> b.getWeight().compareTo(a.getWeight()));
inventory.sort(Comparator.comparing((Apple a) -> a.getWeight()));//按照重量升序 方法的引用inventory.sort(Comparator.comparing((Apple a) -> a.getWeight()).reversed());//降序
System.out.println(inventory);
可以在函数式接口上使用Lambda表达式
java8中提供很多函数式接口,可以直接使用
Predicate
Consumer 定义了一个accept抽象方法,接受泛型T 无返回
Function
Supplier
针对专门的输入参数类型的函数式接口的名称都要加上对应的原始类型前缀。(好像隐式转换)
DoublePredicate,IntConsumer
(List>
()->new Apple(10) 利用了Supplier
(Apple a) -> System.out.println(a.getWeight()) 利用了Consumer(Apple)
(String s)-> s.length() 利用了 Function(String,Integer)或ToIntFunction
任何函数式接口都不允许抛出受检查异常(checked exception)。如果需要Lambda表达式来抛异常,有两种办法
定义一个自己的函数式接口,并声明受检异常,或者把Lambda包在一个try/catch 块中
List
List
filter 返回boolean的函数
filter(Dish::isSmart)
distinct 去重复 distinct()
limit(3) 截取 返回前3个元素
skip(3) 去掉前三个返回剩下的
map(Car::getName) 接受一个函数做为参数,这个函数会被应用到每个元素上,并将其映射成一个新的元素。
返回所有车的名字,可以连续调用map。map(Car::getName).map(String::length) 返回车名字的长度。
对于分隔单词 word.split("") 返回的是数组,一个单词一个数组
words.stream().map(w->w.split("")).flatMap(Arrays::stream).distinct().collect(Collectors.toList());
sorted(comparing(Car::getName)) 按照名称排序
forEach(System.out::println);//打印每个值
短路流 找到就结束不用遍历所有
anyMatch 是否至少匹配一个元素
cars.stream().anyMatch(Car::isBig) 汽车列表里是否有大型车
allMatch 是否匹配所有元素
noneMatch 是否没有任何元素与给定的谓词匹配
findAny 查找元素 返回当前流中的任意元素。与其他流配合使用,只要找到就结束
findFirst() 找到第一个元素
int product = number.stream().reduce(0,(a,b)->a+b);
int product = number.stream().reduce(0,Integer::sum);//Integer::max Integer::min 最大值 最小值
Optional
int product = number.stream().reduce(1,(a,b)->a*b); //所有数相乘 初始值为1,若为0则结果都为0.
long count = cars.stream().count();//计算元素个数
int 重量 = menu.stream().mapToInt(Fish::getWeight).sum();//列表中鱼的重量求和 利用mapToInt的sum方法
两种求和返回值类型不同
Optional num = list.stream().map(Student::getAge).reduce(Integer::sum);
System.out.println(num); // Optional[80]
int sum = list.stream().mapToInt(Student::getAge).sum();
System.out.println(sum); // 80
Colletors类专门为汇总提供了一个工厂方法:Collectors.summingInt。它可以接受一个把对象映射为求和所需int的函数
并返回一个收集器。该收集器在传递给普通的collect方法后即执行我们需要的汇总操作。
int totalAge = list.stream().collect(Collectors.summingInt(Student::getAge));//求和
int totalAges = list.stream().collect(Collectors.reducing(0,Student::getAge,Integer::sum));//求和
Double avgAge = list.stream().collect(Collectors.averagingInt(Student::getAge));//平均数
//总和 平均值 最大 最小 收集器
IntSummaryStatistics studentmenu = list.stream().collect(Collectors.summarizingInt(Student::getAge));
System.out.println(studentmenu);//IntSummaryStatistics{count=5, sum=80, min=12, average=16.000000, max=22}
String allName = list.stream().map(Student::getName).collect(Collectors.joining());//连接字符串
Map> map =list.stream().collect(Collectors.groupingBy(Student::getName));
结果:{st2=[com.sy.Student@6576fe71], st1=[com.sy.Student@76fb509a, com.sy.Student@300ffa5d], st3=[com.sy.Student@1f17ae12, com.sy.Student@4d405ef7]}
还可以多级分组名字分组后再用年龄分组
Map>> mapstudent =
list.stream()
.collect(
Collectors.groupingBy(
Student::getName,
Collectors.groupingBy(
d -> {
if (d.getAge() < 13) return "123";
else return "456";
})));
结果:{st2={456=[com.sy.Student@6576fe71]}, st1={123=[com.sy.Student@76fb509a], 456=[com.sy.Student@300ffa5d]}, st3={456=[com.sy.Student@1f17ae12, com.sy.Student@4d405ef7]}}
还可以在子集里收集数据 列如取子集里最大值maxBy
分区,按照Boolean分区,若对象中有一个boolean属性,可以按照该属性分区 。partitioningBy()
收集器
Collectors类的静态工厂方法
toList 收集到一个List里
toSet 收集到一个set,删除重复项
toCollection 收集到一个Collection<对象>
counting() 计算流中个数 long