Java8 Stream API 笔记
常用的stream操作,做个记录,方便日后使用查询。
[TOC]
1. filter()
接口定义: Stream
说明:
Returns a stream consisting of the elements of this stream that match the given predicate.
返回stream中满足给定过滤条件的元素。
常用情景:
@Test
public void testFilter() {
List users = buildUsers();
System.out.println("爱好为球类运动的同学:");
users.stream().filter(o -> SportTypeEnum.BALL_GAME.equals(o.getHobby().getType())).forEach(System.out::println);
System.out.println("爱球类的女生:");
users.stream().filter(o -> o.getSex().equals(SEXEnum.GIRL) && SportTypeEnum.BALL_GAME.equals(o.getHobby().getType())).forEach(System.out::println);
System.out.println("爱田径运动的姓\"JOBS\"女生:");
users.stream().filter(o -> o.getSex().equals(SEXEnum.GIRL) && SportTypeEnum.ATHLETICS.equals(o.getHobby().getType()) && o.getName().endsWith("JOBS")).forEach(System.out::println);
//收集结果集
List ballGameUser = users.stream().filter(o -> SportTypeEnum.BALL_GAME.equals(o.getHobby().getType())).collect(Collectors.toList());
System.out.println(ballGameUser);
}
输出结果如下:
爱好为球类运动的同学:
StreamTest.Student(id=1, grade=1, name=TOM.F, sex=BOY, age=10, hobby=StreamTest.Hobby(type=BALL_GAME, name=篮球))
StreamTest.Student(id=2, grade=2, name=B.M, sex=BOY, age=18, hobby=StreamTest.Hobby(type=BALL_GAME, name=足球))
StreamTest.Student(id=3, grade=1, name=C.F, sex=GIRL, age=19, hobby=StreamTest.Hobby(type=BALL_GAME, name=台球))
爱球类的女生:
StreamTest.Student(id=3, grade=1, name=C.F, sex=GIRL, age=19, hobby=StreamTest.Hobby(type=BALL_GAME, name=台球))
爱田径运动的姓"JOBS"女生:
StreamTest.Student(id=4, grade=2, name=S.JOBS, sex=GIRL, age=22, hobby=StreamTest.Hobby(type=ATHLETICS, name=跑步))
[StreamTest.Student(id=1, grade=1, name=TOM.F, sex=BOY, age=10, hobby=StreamTest.Hobby(type=BALL_GAME, name=篮球)), StreamTest.Student(id=2, grade=2, name=B.M, sex=BOY, age=18, hobby=StreamTest.Hobby(type=BALL_GAME, name=足球)), StreamTest.Student(id=3, grade=1, name=C.F, sex=GIRL, age=19, hobby=StreamTest.Hobby(type=BALL_GAME, name=台球))]
2. map()
接口定义:
说明:
Returns a stream consisting of the results of applying the given function to the elements of this stream.
对流中的每个元素执行一个函数,使得元素转换成另一种类型输出。
流会将每一个元素输送给map函数,并执行map中的Lambda表达式,最后将执行结果存入一个新的流中。
@Test
public void testMap() {
System.out.println("获取全部姓名:");
List names = students.stream().map(Student::getName).collect(Collectors.toList());
System.out.println(names);
System.out.println("构建map:");
Map userMap = students.stream().collect(Collectors.toMap(Student::getId, Function.identity()));
System.out.println(JSON.toJSONString(userMap));
Map>> userMapByGrade
= students.stream().collect(Collectors.groupingBy(Student::getGrade, Collectors.groupingBy(u -> u.getHobby().getType())));
userMapByGrade.forEach((k, v) -> System.out.println(k + "班: " + JSON.toJSONString(v)));
Map userCountMap
= students.stream().collect(Collectors.groupingBy(Student::getGrade, Collectors.summarizingInt(Student::getAge)));
userCountMap.forEach((k, v) -> System.out.println(k + "班平均年龄 - " + String.format("%.1f岁", v.getAverage())));
userCountMap.forEach((k, v) -> System.out.println(k + "班人数 - " + String.format("%d人", v.getCount())));
userCountMap.forEach((k, v) -> System.out.println(k + "班最小年龄为 - " + String.format("%d岁", v.getMin())));
userCountMap.forEach((k, v) -> System.out.println(k + "班最大年龄为 - " + String.format("%d岁", v.getMax())));
}
- 输出结果:
获取全部姓名:
[TOM.F, B.M, C.F, S.JOBS, E.T, F.JOBS]
构建map:
{1:{"age":10,"grade":1,"hobby":{"name":"篮球","type":"BALL_GAME"},"id":1,"name":"TOM.F","sex":"BOY"},2:{"age":18,"grade":2,"hobby":{"name":"足球","type":"BALL_GAME"},"id":2,"name":"B.M","sex":"BOY"},3:{"age":19,"grade":1,"hobby":{"name":"台球","type":"BALL_GAME"},"id":3,"name":"C.F","sex":"GIRL"},4:{"age":22,"grade":2,"hobby":{"name":"跑步","type":"ATHLETICS"},"id":4,"name":"S.JOBS","sex":"GIRL"},5:{"age":17,"grade":1,"hobby":{"name":"跳高","type":"ATHLETICS"},"id":5,"name":"E.T","sex":"BOY"},6:{"age":22,"grade":2,"hobby":{"name":"跑步","type":"ATHLETICS"},"id":6,"name":"F.JOBS","sex":"UNKNOWN"}}
1班: {"ATHLETICS":[{"age":17,"grade":1,"hobby":{"name":"跳高","type":"ATHLETICS"},"id":5,"name":"E.T","sex":"BOY"}],"BALL_GAME":[{"age":10,"grade":1,"hobby":{"name":"篮球","type":"BALL_GAME"},"id":1,"name":"TOM.F","sex":"BOY"},{"age":19,"grade":1,"hobby":{"name":"台球","type":"BALL_GAME"},"id":3,"name":"C.F","sex":"GIRL"}]}
2班: {"ATHLETICS":[{"age":22,"grade":2,"hobby":{"name":"跑步","type":"ATHLETICS"},"id":4,"name":"S.JOBS","sex":"GIRL"},{"age":22,"grade":2,"hobby":{"name":"跑步","type":"ATHLETICS"},"id":6,"name":"F.JOBS","sex":"UNKNOWN"}],"BALL_GAME":[{"age":18,"grade":2,"hobby":{"name":"足球","type":"BALL_GAME"},"id":2,"name":"B.M","sex":"BOY"}]}
1班平均年龄 - 15.3岁
2班平均年龄 - 20.7岁
1班人数 - 3人
2班人数 - 3人
1班最小年龄为 - 10岁
2班最小年龄为 - 18岁
1班最大年龄为 - 19岁
2班最大年龄为 - 22岁
3. distinct()
去重, 不解释。
@Test
public void testDistinct() {
System.out.println("before: " + students.size());
Student duplicatedStudent = Student.builder().id(1).grade(1).age(10).name("TOM.F").sex(SEXEnum.BOY)
.hobby(Hobby.builder().type(SportTypeEnum.BALL_GAME).name("篮球").build()).build();
students.add(duplicatedStudent);
students = students.stream().distinct().collect(Collectors.toList());
System.out.println("after distinct: " + students.size());
}
*输出结果:
before: 6
after distinct: 6
* 数据准备
/**
* 性别枚举
*/
@AllArgsConstructor
enum SEXEnum {
UNKNOWN(0, "未知"),
BOY(1, "男生"),
GIRL(2, "女生");
private static Map map =
Arrays.stream(SEXEnum.values()).collect(Collectors.toMap(SEXEnum::getCode, sexEnum -> sexEnum));
@Getter
private Integer code;
@Getter
private String sex;
public static SEXEnum getEnumByCode(Integer code) {
return Optional.ofNullable(map.get(code)).orElse(SEXEnum.UNKNOWN);
}
}
/**
* 体育运动枚举
*/
@AllArgsConstructor
enum SportTypeEnum {
OTHERS(0, "其他"),
BALL_GAME(1, "球类"),
ATHLETICS(2, "田径");
private static Map map =
Arrays.stream(SportTypeEnum.values()).collect(Collectors.toMap(SportTypeEnum::getCode, sportTypeEnum -> sportTypeEnum));
@Getter
private Integer code;
@Getter
private String sex;
public static SportTypeEnum getEnumByCode(Integer code) {
return Optional.ofNullable(map.get(code)).orElse(SportTypeEnum.OTHERS);
}
}
/**
* 学生类定义
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
static class Student {
private Integer id;
/**
* 年级
*/
private Integer grade;
/**
* 姓名
*/
private String name;
/**
* 性别
*
* @see SEXEnum
*/
private SEXEnum sex;
/**
* 年龄
*/
private Integer age;
/**
* 爱好
*
* @see Hobby
*/
private Hobby hobby;
}
/**
* 兴趣爱好枚举
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
static class Hobby {
/**
* 体育运动类型
*
* @see SportTypeEnum
*/
private SportTypeEnum type;
/**
* 体育运动名称
*/
private String name;
}
构建一个学生对象集合:
private List buildUsers() {
Student student1 = Student.builder().id(1).grade(1).age(10).name("TOM.F").sex(SEXEnum.BOY)
.hobby(Hobby.builder().type(SportTypeEnum.BALL_GAME).name("篮球").build()).build();
Student student2 = Student.builder().id(2).grade(2).age(18).name("B.M").sex(SEXEnum.BOY)
.hobby(Hobby.builder().type(SportTypeEnum.BALL_GAME).name("足球").build()).build();
Student student3 = Student.builder().id(3).grade(1).age(19).name("C.F").sex(SEXEnum.GIRL)
.hobby(Hobby.builder().type(SportTypeEnum.BALL_GAME).name("台球").build()).build();
Student student4 = Student.builder().id(4).grade(2).age(22).name("S.JOBS").sex(SEXEnum.GIRL)
.hobby(Hobby.builder().type(SportTypeEnum.ATHLETICS).name("跑步").build()).build();
Student student5 = Student.builder().id(5).grade(1).age(17).name("E.T").sex(SEXEnum.BOY)
.hobby(Hobby.builder().type(SportTypeEnum.ATHLETICS).name("跳高").build()).build();
Student student6 = Student.builder().id(6).grade(2).age(22).name("F.JOBS").sex(SEXEnum.UNKNOWN)
.hobby(Hobby.builder().type(SportTypeEnum.ATHLETICS).name("跑步").build()).build();
return Lists.newArrayList(student1, student2, student3, student4, student5, student6);
}