java 8 stream+lambda 简化集合操作

目录

1.利用stream创建集合

   1.1   Stream.of 创建

1.2 利用 Stream.iterate 创建

2. 遍历 forEach

3.查找  find

4.匹配 match

5.筛选 filter

6.映射 map/flatMap

7.归约 reduce

8.排序 sorted

9.收集 collect

10.list转map

11.去重

12.分组

13.方法

    13.1 map()

13.2 filter()

13.3 limit()

13.4 skip()

13.5 distinct()

13.6 peek()

13.7 collect()

14 map转 list

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());

未完待续...

猜你喜欢

转载自blog.csdn.net/weixin_41018853/article/details/131956470