目录
1.利用stream创建集合
1.1 Stream.of 创建
public static void main(String[] args) {
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
List<Integer> collect = stream.collect(Collectors.toList());
collect.stream().forEach(System.out::print);
}
输出 12345
1.2 利用 Stream.iterate 创建
public static void main(String[] args) {
Stream<Integer> stream = Stream.iterate(0, (x) -> x + 2).limit(3); // 输出 0,2,4
Stream<String> stream2 = Stream.generate(() -> "Hello").limit(3); // 输出 Hello,Hello,Hello
Stream<Double> stream3 = Stream.generate(Math::random).limit(3); // 输出3个随机数
}
2. 遍历 forEach
// 循环输出user对象 users是个集合
users.stream().forEach(user -> System.out.println(user));
3.查找 find
// 取出第一个对象
User user = users.stream().findFirst().orElse(null); // 输出 {"age":1,"name":"Tom"}
// 随机取出任意一个对象
User user = users.stream().findAny().orElse(null);
4.匹配 match
// 判断是否存在name是Tom的用户
boolean existTom = users.stream().anyMatch(user -> "Tom".equals(user.getName()));
// 判断所有用户的年龄是否都小于5
boolean checkAge = users.stream().allMatch(user -> user.getAge() < 5);
5.筛选 filter
// 筛选name是Tom的用户
users.stream()
.filter(user -> "Tom".equals(user.name))
.forEach(System.out::println); // 输出 {"age":1,"name":"Tom"}
//过滤手机号为空和null的数据,获取手机号集合
List<String> phoneList = result.stream()
.filter((YwOnlineUser p) -> p.getFromPhone() != null|| p.getFromPhone() !="")
.map(YwOnlineUser::getFromPhone)
.collect(Collectors.toList());
//过滤selectionList集合中存在的数据
exportList = pageList.stream().filter(item -> selectionList.contains(item.getId())).collect(Collectors.toList());
6.映射 map/flatMap
// 打印users里的name
users.stream().map(User::getName).forEach(System.out::println); // 输出 Tom Jerry
// List<List<User>> 转 List<User>
List<List<User>> userList = new ArrayList<>();
List<User> users = userList.stream().flatMap(Collection::stream).collect(Collectors.toList());
7.归约 reduce
// 求用户年龄之和
Integer sum = users.stream().map(User::getAge).reduce(Integer::sum).orElse(0);
// 求用户年龄的乘积
Integer product = users.stream().map(User::getAge).reduce((x, y) -> x * y).orElse(0);
8.排序 sorted
// 按年龄倒序排
List<User> collect = users.stream()
.sorted(Comparator.comparing(User::getAge).reversed())
.collect(Collectors.toList());
//多属性排序
List<Person> result = persons.stream()
.sorted(Comparator.comparing((Person p) -> p.getNamePinyin())
.thenComparing(Person::getAge)).collect(Collectors.toList());
9.收集 collect
// list转换成map
Map<Integer, User> map = users.stream()
.collect(Collectors.toMap(User::getAge, Function.identity()));
// 按年龄分组
Map<Integer, List<User>> userMap = users.stream().collect(Collectors.groupingBy(User::getAge));
// 求平均年龄
Double ageAvg = users.stream().collect(Collectors.averagingInt(User::getAge));
// 求年龄之和
Integer ageSum = users.stream().collect(Collectors.summingInt(User::getAge));
// 求年龄最大的用户
User user = users.stream().collect(Collectors.maxBy(Comparator.comparing(User::getAge)))
.orElse(null);
// 把用户姓名拼接成逗号分隔的字符串输出
String names = users.stream().map(User::getName).collect(Collectors.joining(","));
10.list转map
//key冲突选择第一个
Map<Integer,User> map = users.stream().collection(Collectors.toMap(User::getId,user->user,(user1,user2)->user1));
//集合转map
Map<String, AppLogin> map = list.stream().collect(Collectors.toMap(AppLogin::getId, Function.identity(),(d1,d2)->d1));
//取集合中实体的两个字段作为key和 value
Map<String, Integer> collect =customerUserList.stream().collect(Collectors.toMap(YwCustomerUser::getCustomerId, YwCustomerUser::getEditPermissions));
11.去重
ArrayList<User> collect = list
.stream()
.collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(User::getName))), ArrayList::new));
List<YwOnlineUser> result = pageList.getRecords().stream().collect(Collectors.collectingAndThen(
Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(YwOnlineUser::getFromPhone))), ArrayList::new
));
12.分组
//按照部门编码分组 部门编码 key 相同部门value
Map<String, List<Depart>> orgCodeMap =
list.stream().collect(Collectors.groupingBy(Depart::getSysOrgCode));
//list1和pageList存储的是用户信息,并且两个集合的手机号都有重复,
//如果 pageList中的手机号存在list1中,那么 pageList 的 LinkPeople LinkDate 要设置成 list1
// 中相同手机号的 LinkPeople LinkDate,否则 pageList 循环的实体不需要改变
List<YwOnlineUser> collect = pageList.getRecords().stream().map(item -> list1.stream().filter(
rea -> item.getFromPhone().equals(rea.getFromPhone())).findFirst().map(rea -> {
item.setLinkPeople(rea.getLinkPeople());
item.setLinkDate(rea.getLinkDate());
return item;
}).orElse(item)
).collect(Collectors.toList());
//和上一个相同,返回的是新组装的实体
List<YwOnlineUser> collect = exportList.stream().map(item -> list1.stream().filter(
rea -> item.getFromPhone().equals(rea.getFromPhone())).findFirst().map(rea -> {
YwOnlineUser user= new YwOnlineUser();
user.setLinkPeople(userMap.get(rea.getLinkPeople()));
user.setLinkDate(rea.getLinkDate());
user.setFlag(stringJSONObjectMap.get("flag").getString(item.getFlag()));
user.setStatus(stringJSONObjectMap.get("onlineuser").getString(item.getStatus()));
if(StringUtils.isNotBlank(stringJSONObjectMap.get("channel").getString(item.getType()))){
user.setType(stringJSONObjectMap.get("channel").getString(item.getType()));
}else{
user.setType("线上用户");
}
user.setFromPhone(item.getFromPhone());
user.setFpDate(item.getFpDate());
user.setName(item.getName());
user.setPhone(item.getPhone());
return user;
}).orElse(
item.setFlag(stringJSONObjectMap.get("flag").getString(item.getFlag()))
.setStatus(stringJSONObjectMap.get("onlineuser").getString(item.getStatus()))
.setType(StringUtils.isNotBlank(stringJSONObjectMap.get("channel").getString(item.getType()))?stringJSONObjectMap.get("channel").getString(item.getType()):"在线用户")
)
).collect(Collectors.toList());
13.方法
13.1 map()
map是stream中非常常用的一个方法,它用于映射每个元素到对应的结果里面,可以让你提取对象中的某一个属性或者转化成其它的对象
List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
List<Integer> squaresList = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());
System.out.println(squaresList);
//输出结果:[9, 4, 49, 25] 其中distinct()是去掉重复的值。
//将用户的名字提取出来转成字符串集
List<String> collect = list.stream().map(x -> x.getName()).collect(Collectors.toList());
//将结果转成另一个对象
List<User> result = list.stream().map(temp -> {
User obj = new User();
obj.setName(temp.getName());
obj.setAge(temp.getAge());
if ("ricky".equals(temp.getName())) {
obj.setExtra("this field is for ricky only!");
}
return obj;
}).collect(Collectors.toList());
13.2 filter()
filter 主要用于通过设置的条件过滤出符合的元素,类似于一个过滤器。
List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
// 获取空字符串的数量
long count = strings.stream().filter(string -> string.isEmpty()).count();
// 输出结果:2
List<StudentInfo> studentList = new ArrayList<>();
studentList.add(new StudentInfo("李小明",true,18,1.76,LocalDate.of(2001,3,23)));
studentList.add(new StudentInfo("张小丽",false,18,1.61,LocalDate.of(2001,6,3)));
studentList.add(new StudentInfo("王大朋",true,19,1.82,LocalDate.of(2000,3,11)));
studentList.add(new StudentInfo("陈小跑",false,17,1.67,LocalDate.of(2002,10,18)));
List<StudentInfo> boys = studentList.stream().filter(s->s.getGender() && s.getHeight() >= 1.8)
.collect(Collectors.toList());
StudentInfo.printStudents(boys);
// 输出 "王大朋",true,19,1.82,2002-10-18 gender解释 false代表女生 true代表男生
13.3 limit()
limit 对一个Stream进行截断操作,获取其前N个元素。如果原Stream中包含的元素个数小于N,那就获取其所有的元素
List<String> strings = Arrays.asList("abc", "dd", "bc", "efg", "abcd","cc", "jkl");
strings.stream().limit(2).forEach(System.out::println);
//输出 abc dd
13.4 skip()
skip 可以对流进行一个跳过操作,可以通过自定义的数值N去跳过前N个元素。
List<String>strings = Arrays.asList("abc", "dd", "bc", "efg", "abcd","cc", "jkl");
strings.stream().skip(3).forEach(System.out::println);
// 输出结果
efg
abcd
cc
jkl
13.5 distinct()
distinct 是对流进行一个去重的操作,是通过元素的hashcode()和equals()去判断两个元素是否一致的,这样我们在使用对象去重的时候,可以通过重写它的hascode和equals方法就可以达到我们想要的效果了。
List<String>strings = Arrays.asList("abc", "dd", "bc", "abc", "bc","cc", "dd");
strings.stream().distinct().forEach(System.out::println);
// 输出结果
abc
dd
bc
cc
13.6 peek()
peek 生成一个包含原Stream的所有元素的新Stream,同时会提供一个消费函数(Consumer实例),新Stream每个元素被消费的时候都会执行给定的消费函数,peek主要被用在debug用途。
Stream.of("one", "two", "three","four").filter(e -> e.length() > 3)
.peek(e -> System.out.println("Filtered value: " + e))
.map(String::toUpperCase)
.peek(e -> System.out.println("Mapped value: " + e))
.collect(Collectors.toList());
//输出
Filtered value: three
Mapped value: THREE
Filtered value: four
Mapped value: FOUR
13.7 collect()
collect 方法的功能是将 Stream 中数据转换为最终的结果
//转换成list
List collect1 = num.stream().map(n -> n * 2).collect(Collectors.toList());
//转成ArrayList
ArrayList<String> list = stream.collect(Collectors.toCollection(ArrayList::new));
//转成TreeSet
TreeSet<String> treeSet = stream.collect(Collectors.toCollection(TreeSet::new));
Stream<String> stream = Stream.of("hello", "world", "helloworld");
String s = stream.collect(Collectors.joining(","));
System.out.println(s);
//输出
hello,world,helloworld
//获取集合名称集合 Collectors.mapping 映射
List<Employee> list = new ArrayList<>();
list.add(new Employee("张三", 33));
list.add(new Employee("李四", 28));
list.add(new Employee("王五", 25));
list.add(new Employee("赵六", 40));
list.add(new Employee("孙七", 18));
String nameList = list.stream().collect(Collectors.mapping(Employee::getName, Collectors.joining(",")));
System.out.println(nameList);
//输出结果
张三,李四,王五,赵六,孙七
//Collectors.minBy 比较取小
Employee employee = list.stream().collect(Collectors.minBy(Comparator.comparingInt(Employee::getAge))).get();
//Collectors.maxBy 比较取大
Employee employee = list.stream().collect(Collectors.maxBy (Comparator.comparingInt(Employee::getAge))).get();
//Collectors.summarizingInt 年龄求和,此外还有summarizingDouble与summarizingLong,用法一致。
long sum = list.stream().collect(Collectors.summarizingInt(Employee::getAge)).getSum();
//Collectors.averagingInt 年龄求平均值,此外还有averagingDouble与averagingLong,用法一致。
Double avgAge = list.stream().collect(Collectors.averagingInt(Employee::getAge));
//Collectors.groupingBy分组,整理出的结果以Map的形式展现。
List<Employee> list = new ArrayList<>();
list.add(new Employee("张三", 20));
list.add(new Employee("李四", 20));
list.add(new Employee("王五", 30));
list.add(new Employee("赵六", 30));
list.add(new Employee("孙七", 40));
Map<Integer, List<Employee>> employeeMap = list.stream().collect(Collectors.groupingBy(Employee::getAge));
for (Integer age : employeeMap.keySet()) {
System.out.println(age+"年龄组有");
employeeMap.get(age).stream().forEach(System.out::println);
}
//输出结果
20年龄组有
Employee(name=张三, age=20)
Employee(name=李四, age=20)
40年龄组有
Employee(name=孙七, age=40)
30年龄组有
Employee(name=王五, age=30)
Employee(name=赵六, age=30)
//Collectors.partitioningBy 条件分组,整理出的结果以Map的形式展现,key为Boolean类型,true一组,false一组。
List<Employee> list = new ArrayList<>();
list.add(new Employee("张三", 33));
list.add(new Employee("李四", 28));
list.add(new Employee("王五", 25));
list.add(new Employee("赵六", 40));
list.add(new Employee("孙七", 18));
//年龄是否大于30
Map<Boolean, List<Employee>> employeeMap = list.stream().collect(Collectors.partitioningBy(k -> k.getAge().compareTo(30) > 0));
for (Boolean b : employeeMap.keySet()) {
System.out.println(b ? "大于30的有" : "小于30的有");
employeeMap.get(b).stream().forEach(System.out::println);
}
//输出结果
小于30的有
Employee(name=李四, age=28)
Employee(name=王五, age=25)
Employee(name=孙七, age=18)
大于30的有
Employee(name=张三, age=33)
Employee(name=赵六, age=40)
//Collectors.toMap 将结果转换成Map
List<Employee> list = new ArrayList<>();
list.add(new Employee("张三", 33));
list.add(new Employee("李四", 28));
list.add(new Employee("王五", 25));
list.add(new Employee("赵六", 40));
list.add(new Employee("孙七", 18));
//年龄是否大于30
Map<String, Employee> employeeMap = list.stream().collect(Collectors.toMap(k -> k.getName(), v -> v, (o1, o2) -> o1));
for (String name : employeeMap.keySet()) {
System.out.println(name + "年龄是:" + employeeMap.get(name).getAge() + "岁");
}
//输出结果
孙七年龄是:18岁
李四年龄是:28岁
张三年龄是:33岁
王五年龄是:25岁
赵六年龄是:40岁
14 map转 list
//在map里面构造数据 return什么数据就转成什么类型的list
List<Employee> collect = map.entrySet().stream().map(item -> {
Employee employee = new Employee();
employee.setId(item.getKey());
employee.setEmpName(item.getValue());
return employee;
}).collect(Collectors.toList());
// concat:合并两个流 distinct:去重
List<String> newList = Stream.concat(stream1, stream2).distinct().collect(Collectors.toList());
未完待续...