目录
3.2.4、sorted排序+reversed倒序+thenComparing多条件
3.2.10.1、Collectors.toList() 转list
3.2.10.2、Collectors.toMap() 转map
3.2.10.3、Collectors.toSet() 转set
3.2.10.4、Collectors.groupingBy() 分组
3.2.10.5、Collectors.joining() 转字符串
3.2.11、anyMatch只要有一条数据满足条件即返回true
3.2.12、allMatch必须全部都满足条件才会返回true
3.2.13、noneMatch全都不满足条件才会返回true
一、概述
lambda表达式是JDK8中的一个新特性,对某些匿名内部类进行简化,是函数式编程;
二、基本格式
(参数列表)->{方法体代码}
三、Stream流
- 是jdk8中的新特性,将集合或者数组数据以流的形式进行操作
3.1、准备
@AllArgsConstructor
@NoArgsConstructor
@Data
public class People {
private int id;
private String name;
private int age;
private String home;
private List<Friend> friendList;
}
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Friend {
private int id;
private String name;
private int age;
private String home;
private String category;//分类
}
void contextLoads() {
People people1=new People(1,"曹操",33,"魏国",null);
People people2=new People(2,"孙权",15,"吴国",null);
People people3=new People(3,"张飞",14,"蜀国",null);
People people4=new People(3,"张飞",14,"蜀国",null);
List<Friend>list1=new ArrayList<>();
List<Friend>list2=new ArrayList<>();
List<Friend>list3=new ArrayList<>();
list1.add(new Friend(1,"刘备",88,"河北,石家庄","好朋友"));
list1.add(new Friend(2,"赵云",99,"湖北,武汉","新朋友"));
list2.add(new Friend(3,"周瑜",85,"辽宁,大连","老朋友"));
list2.add(new Friend(3,"周瑜",85,"辽宁,大连","老朋友"));
list2.add(new Friend(4,"诸葛亮",56,"内蒙古,包头","大朋友"));
list3.add(new Friend(5,"郭嘉",56,"甘肃,兰州","骄傲的朋友"));
list3.add(new Friend(6,"吕布",100,"陕西,西安","厉害的朋友"));
list3.add(new Friend(7,"吕布",100,"陕西,西安","厉害的朋友"));
people1.setFriendList(list1);
people2.setFriendList(list2);
people3.setFriendList(list3);
people4.setFriendList(list3);
List<People>peopleList=new ArrayList<>(Arrays.asList(people1,people2,people3,people4));
}
3.2、常用方法
3.2.1 filter过滤 | |
//筛选年龄大于15的people
peopleList.stream().filter(new Predicate<People>() {
@Override
public boolean test(People people) {
return people.getAge()>15;
}
}).forEach(new Consumer<People>() {
@Override
public void accept(People people) {
System.out.println(people);
}
}); | ----Alt+Enter转为Lambda表达式----
peopleList.stream()
.filter(people -> people.getAge()>15)
.forEach(people -> System.out.println(people)); |
3.2.2、distinct去重 | |
//去除重复数据
peopleList.stream().distinct().forEach(new Consumer<People>() {
@Override
public void accept(People people) {
System.out.println(people);
}
}); | ----Alt+Enter转为Lambda表达式----
peopleList.stream()
.distinct()
.forEach(people -> System.out.println(people)); |
3.2.3、map映射成一个新的元素 | |
//打印people中的名字,放到List集合中
List<Object> collect = peopleList.stream().map(new Function<People, Object>() {
@Override
public Object apply(People people) {
return people.getName();
}
}).collect(Collectors.toList());
System.out.println(collect); | ----Alt+Enter转为Lambda表达式----
List<Object> collect = peopleList.stream()
.map(people -> people.getName())
.collect(Collectors.toList());
System.out.println(collect); |
3.2.4、sorted排序+reversed倒序+thenComparing多条件 | |
//根据people中的年龄进行升序排序
peopleList.stream()
.sorted(new Comparator<People>() {
@Override
public int compare(People o1, People o2) {
return o1.getAge()-o2.getAge();
}
}).forEach(new Consumer<People>() {
@Override
public void accept(People people) {
System.out.println(people);
}
}); ******************************** //根据people中的Id和年龄进行倒序排序 peopleList.stream() .sorted(Comparator.comparing(new Function<People, Integer>() { @Override public Integer apply(People people) { return people.getId(); } }).thenComparing(new Function<People, Integer>() { @Override public Integer apply(People people) { return people.getAge(); } }).reversed()) .forEach(people -> System.out.println(people)); | ----Alt+Enter转为Lambda表达式----
peopleList.stream()
.sorted((o1, o2) -> o1.getAge()-o2.getAge())
.forEach(people -> System.out.println(people));
******************************** peopleList.stream() .sorted(Comparator.comparing(People::getId) .thenComparing(People::getAge) .reversed()) .forEach(people -> System.out.println(people)); |
3.2.5、limit取前几条元素3.2.6、skip跳过前几条数据 | |
//取前3条数据
List<People> list = peopleList.stream().limit(3).collect(Collectors.toList());
System.out.println(list); | |
3.2.7、flatMap合并流
| |
//获取所有people中每个people的friend的名字
peopleList.stream()
.flatMap(new Function<People, Stream<Friend>>() {
@Override
public Stream<Friend> apply(People people) {
return people.getFriendList().stream();
}
}).forEach(new Consumer<Friend>() {
@Override
public void accept(Friend friend) {
System.out.println(friend.getName());
}
}); | ----Alt+Enter转为Lambda表达式----
peopleList.stream()
.flatMap(people -> people.getFriendList().stream())
.forEach(friend -> System.out.println(friend.getName())); |
3.2.8、count计算数量 | |
//获取所有people中每个people的friend的数量
long num=peopleList.stream().flatMap(people -> people.getFriendList().stream())
.count();
System.out.println(num); | |
3.2.9、max计算最大和min计算最小 | |
//获取所有people中的friend的年龄最大的
Optional<People> max = peopleList.stream().max(new Comparator<People>() {
@Override
public int compare(People o1, People o2) {
return o1.getAge() - o2.getAge();
}
});
System.out.println(max.get()); | ----Alter+Enter转为Lambda表达式----
Optional<People> max = peopleList.stream()
.max((o1, o2) -> o1.getAge() - o2.getAge());
System.out.println(max.get()); |
3.2.10、collect转换成新集合3.2.10.1、Collectors.toList() 转list3.2.10.2、Collectors.toMap() 转map3.2.10.3、Collectors.toSet() 转set3.2.10.4、Collectors.groupingBy() 分组3.2.10.5、Collectors.joining() 转字符串 | |
//获取所有people中的名字转换为新的集合 List<String>names=peopleList.stream() .map(people -> people.getName()) .collect(Collectors.toList()); System.out.println(names); //获取所有people中的friend集合转set Set<Friend>set=peopleList.stream() .flatMap(people -> people.getFriendList().stream()) .collect(Collectors.toSet()); System.out.println(set); //以people集合中的名字为键,friend集合为值,转map Map<String,List<Friend>>map=peopleList.stream().distinct() .collect(Collectors.toMap(people -> people.getName(), people -> people.getFriendList())); System.out.println(map); //groupingBy分组 Map<String, List<People>> collect = peopleList.stream() .collect(Collectors.groupingBy(people -> people.getName())); System.out.println(collect); //joinging拼接成字符串 String names = peopleList.stream() .map(people -> people.getName()).collect(Collectors.joining(",")); System.out.println(names); | |
3.2.11、anyMatch只要有一条数据满足条件即返回true3.2.12、allMatch必须全部都满足条件才会返回true3.2.13、noneMatch全都不满足条件才会返回true | |
//以people集合中是否有年龄大于15岁的,有一个结果就为true
boolean ishave=peopleList.stream().anyMatch(new Predicate<People>() {
@Override
public boolean test(People people) {
return people.getAge()>15;
}
}); | ----Alter+Enter转为Lambda表达式----
boolean ishave=peopleList.stream().anyMatch(people -> people.getAge()>15); |
3.2.14、findFirst获取第一条数据 | |
//获取people中年龄最小的第一条数据
Optional<People> first = peopleList
.stream()
.distinct()
.sorted((o1, o2) -> o1.getAge() - o2.getAge())
.findFirst();
first.ifPresent(people -> System.out.println(people)); | |
3.2.15、reduce根据指定的计算模型计算结果 | |
//计算people中每个人的年龄的总和
Integer result=peopleList.stream()
.map(new Function<People, Integer>() {
@Override
public Integer apply(People people) {
return people.getAge();
}
}).reduce(0,new BinaryOperator<Integer>() {
@Override
public Integer apply(Integer integer, Integer integer2) {
System.out.println("integer="+integer+" integer2="+integer2+" integer+integer2="+(integer+integer2));
return integer+integer2;
}
}); ----Alter+Enter转为Lambda表达式----
Integer result=peopleList.stream()
.map(people -> people.getAge())
.reduce(0, (integer, integer2) -> {
System.out.println("integer="+integer+" integer2="+integer2+" integer+integer2="+(integer+integer2));
return integer+integer2;
}); 带初始值的循环计算,第一个integer是每次计算的结果,第二个integer2是每次输入进来的值
| |
//计算people中最小的年龄
Optional<Integer> reduce = peopleList.stream().distinct()
.map(new Function<People, Integer>() {
@Override
public Integer apply(People people) {
return people.getAge();
}
}).reduce(new BinaryOperator<Integer>() {
@Override
public Integer apply(Integer integer, Integer integer2) {
return integer<integer2?integer:integer2;
}
});
| ----Alter+Enter转为Lambda表达式----
Optional<Integer> reduce = peopleList.stream().distinct()
.map(people -> people.getAge())
.reduce((integer, integer2) -> integer<integer2?integer:integer2); |
3.2.16、foreach终结操作
| |
3.2.17、peek中间操作
| |
//不会执行
peopleList.stream()
.peek(people -> System.out.println(people.getName()));
| //会执行
List<People> collect = peopleList.stream()
.peek(people -> System.out.println(people.getName()))
.collect(Collectors.toList());
System.out.println(collect); |
3.2.18、双列集合 | |
Map<String,Integer>map=new HashMap<>(); map.put("aaa",1); map.put("bbb",2); map.put("ccc",3); map.put("ddd",4); Set<Map.Entry<String, Integer>> entries = map.entrySet(); entries.stream().forEach(new Consumer<Map.Entry<String, Integer>>() { @Override public void accept(Map.Entry<String, Integer> stringIntegerEntry) { System.out.println(stringIntegerEntry); } }); entries.stream().forEach(stringIntegerEntry -> System.out.println(stringIntegerEntry)); |
四、Optional
-
避免出现空而创建的
4.1、ofNullable()创建对象可以为null | |
//创建对象
Optional<People> optional = Optional.ofNullable(people); | |
4.2、ifPresent安全消费
| |
//people为空 People people=null; Optional<People> optional = Optional.ofNullable(people); optional.ifPresent(new Consumer<People>() { @Override public void accept(People people) { System.out.println(people); } }); //people不为空 People people22=peopleList.get(0); Optional<People> optional2 = Optional.ofNullable(people22); optional2.ifPresent(new Consumer<People>() { @Override public void accept(People people) { System.out.println(people); } }); | //people为空 People people=null; Optional<People> optional = Optional.ofNullable(people); optional.ifPresent(people5 -> System.out.println(people5)); //people不为空 People people22=peopleList.get(0); Optional<People> optional2 = Optional.ofNullable(people22); optional2.ifPresent(people52 -> System.out.println(people52)); |
4.3、orElseGet安全获取值
| |
//people为空 People peopleNull=null; Optional<People> optional = Optional.ofNullable(peopleNull); People p = optional.orElseGet(new Supplier<People>() { @Override public People get() { return null; } }); System.out.println(p); //people不为空 People peopleNotNull=peopleList.get(0); Optional<People> optionalNotNull = Optional.ofNullable(peopleNotNull); People pp =optionalNotNull.orElseGet(new Supplier<People>() { @Override public People get() { return null; } }); System.out.println(pp); | //people为空 People peopleNull=null; Optional<People> optional = Optional.ofNullable(peopleNull); People p = optional.orElseGet(() -> null); System.out.println(p); //people不为空 People peopleNotNull=peopleList.get(0); Optional<People> optionalNotNull = Optional.ofNullable(peopleNotNull); People pp =optionalNotNull.orElseGet(() -> null); System.out.println(pp); |
4.4、filter安全过滤
| |
//people为空
People peopleNull=null;
Optional<People> optional = Optional.ofNullable(peopleNull);
optional.filter(new Predicate<People>() {
@Override
public boolean test(People people) {
return people.getAge() > 14;
}
}).ifPresent(new Consumer<People>() {
@Override
public void accept(People people) {
System.out.println(people.getName());
}
}); | People peopleNull=null; Optional<People> optional = Optional.ofNullable(peopleNull); optional.filter(people -> people.getAge() > 14) .ifPresent(people -> System.out.println(people.getName())); |
五、函数式接口
- 只有一个抽象方法的接口,但是也可以有其他的方法(默认、静态、私有)
- 一般都加上了@FunctionalInterface注解进行标识,但是也有的函数式接口没有该注解
5.1、常用的默认方法
5.1.1、filter方法的Predicate接口
| |
//获取people中年龄大于14且名字长度大于2
peopleList.stream().filter(new Predicate<People>() {
@Override
public boolean test(People people) {
return people.getAge()>14;
}
}.and(new Predicate<People>() {
@Override
public boolean test(People people) {
return people.getName().length()>2;
}
})).forEach(new Consumer<People>() {
@Override
public void accept(People people) {
System.out.println(people);
}
}); | ----Alter+Enter转Lambda表达式----
peopleList.stream()
.filter(((Predicate<People>) people -> people.getAge() > 14)
.and(people -> people.getName().length()>2))
.forEach(people -> System.out.println(people)); 或者不要and,用&&写一起,可读性会更好 peopleList.stream() .filter(people -> people.getAge()>14 && people.getName().length()>2) .forEach(people -> System.out.println(people)); |
六、函数引用
Alter+enter
转换的结果就是将内部类转换成lambda或者refrence写法 //获取people中年龄大于14且名字长度大于2
peopleList.stream()
.sorted(Comparator.comparing((Function<People, Integer>) people -> people.getId())
.thenComparing(people -> people.getAge()).reversed())
.forEach(people -> System.out.println(people)); peopleList.stream() .sorted(Comparator.comparing(People::getId) .thenComparing(People::getAge).reversed()) .forEach(people -> System.out.println(people)); |
七、串行流和并行流
- 并行流是多线程,串行流是单线程,如果数据量比较大,用并行流
peopleList.stream()创建串行流 |
peopleList.stream().parallel()串行流转成并行 |
peopleList.parallelStream()直接创建并行流 |