Java常用的stream流操作,附源码

导读:本篇文章讲解 Java常用的stream流操作,附源码,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

问题背景

java8的新特性非常有亮点,stream用起来爽歪歪
注意事项:

  • 可以自己创建工程,也可以下载源码进行参考

中间操作

  • filter:过滤流中的某些元素,
  • sorted(): 自然排序,流中元素需实现 Comparable 接口 。
  • distinct: 去除重复元素
  • limit(n): 获取 n 个元素
  • skip(n): 跳过 n 元素,配合 limit(n)可实现分页 map(): 将其映射成一个新的元素

终端操作

  • forEach: 遍历流中的元素
  • toArray: 将流中的元素倒入一个数组
  • min: 返回流中元素最小值
  • max: 返回流中元素最大值
  • count: 返回流中元素的总个数
  • reduce: 所有元素求和
  • anyMatch: 接收一个 Predicate 函数,只要流中有一个元素满足条件则返 回 true,否则返回 false
  • allMatch: 接收一个 Predicate 函数,当流中每个元素都符合条件时才返 回 true,否则返回 false
  • findFirst:返回流中第一个元素
  • collect: 将流中的元素倒入一个集合,Collection 或 Map

stream操作方法

导入类

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.commons.lang3.ArrayUtils;

import static java.util.Comparator.comparing;
import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.toCollection;

1 去重

        List<String> list = new ArrayList<>();
        list.add("a");
        list.add("a");
        List<String> listDistinct = list.stream().distinct().collect(Collectors.toList());
        System.out.println(listDistinct);

2 对象无序去重, 通过name去重

        List<User> userList = new ArrayList();
        userList.add(new User("yuange", 12));
        userList.add(new User("yuange", 12));
        userList.add(new User("yuange1", 14));
        userList.add(new User("yuange1", 15));
        userList.add(new User("pangpang", 12));
        userList.add(new User("pangpang", 12));
        List<User> result = userList.stream()
                .collect(collectingAndThen(toCollection(() ->
                        new TreeSet<>(comparing(User::getName))), ArrayList::new));
        result.forEach(System.out::println);

3 对象无序去重, 通过name且age去重,注意:不是先使用name去重,再使用age去重

        List<User> result1 = userList.stream()
                .collect(collectingAndThen(toCollection(() ->
                        new TreeSet<>(comparing(o -> o.getName() + ";" + o.getAge()))), ArrayList::new));
        result1.forEach(System.out::println);

3.1 对象有序去重

public class StreamUtils{


	//LinkedHashMap有序去重
	private static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) {
	        LinkedHashMap<Object, Boolean> map = new LinkedHashMap<>();
	        return t -> map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
	}
	
	//ConcurrentHashMap无序去重
	private static <T> Predicate<T> distinctByKeyMap(Function<? super T, Object> keyExtractor) {
	        ConcurrentHashMap<Object, Boolean> map = new ConcurrentHashMap<>();
	        return t -> map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
	}
}
List<User> list = new ArrayList<User>();
list.add(new User("小南", 23, "18335888888"));
list.add(new User("小南", 22, "18335888888"));
list.add(new User("小南", 21, "18335888888"));
list.add(new User("小南", 20, "18335888888"));

list = list.stream().filter(StreamUtils.distinctByKey(User :: getName)).collect(Collectors.toList());
System.out.println(list.toString());

4 整个对象去重, 使用distinct需要重写User的equals和hashcode

        List<User> result2 = userList.stream().distinct().collect(Collectors.toList());
        result2.forEach(System.out::println);

5 流的基本操作

        Integer[] integers = new Integer[]{2, 4, 3, 6, 1, 7, 5, 5, 7};
        List<Integer> list1 = Arrays.asList(integers);
        //list1.stream()等价于Stream.of(2,4,3,6,1,7,5,5,7)
        list1.stream()
                //中间操作
                .filter((e) -> {
                    return e > 3;
                })      //使用Lambda的表达式  表示大于3的留下
                //filter的结果为 4,6,7,5,5,7
                .sorted()                           //自然排序,流中元素需实现
                //sorted的结果为 4,5,5,6,7,7
                .distinct()                         //去除重复元素
                //distinct的结果为 4,5,6,7
                .skip(1)                            //跳过 n 元素   这里意思跳过1个元素,从第二个开始
                //skip的结果为 5,6,7
                .limit(2)                           //获取 n 个元素 这里获取了两个元素
                //limit的结果为 5,6
                //终端操作
                .forEach((a) -> {
                    System.out.println(a);
                });

6 取出List中某个属性值

        ArrayList<User> arrayList = new ArrayList<>();
        arrayList.add(new User("小智", 12));
        arrayList.add(new User("张三", 12));
        arrayList.add(new User("蕾姆", 14));
        arrayList.add(new User("亚当", 11));
        arrayList.add(new User("夏娃", 7));
        arrayList.stream()
                //map(方法)将某一个值映射到Stream
                //Apple::getNumber意思是将Apple对象中的number 转换为Stream中的流
                .map(User::getName)
                //之下的操作就是对Apple中所有的number数据进行操作
                .forEach((e) -> {
                    System.out.println(e);
                });
arrayList.stream().map(User::getName).collect(Collectors.toList());

7 转为排序的list

        List<User> list2 = arrayList.stream()
                //中间操作,进行了一个排序的操作
                .sorted((o1, o2) -> {
                    return o1.getAge() - o2.getAge();
                })
                .collect(Collectors.toList());//将处理完后的流转换为List类型的数据
        System.out.println("转换为一个List的集合:");
        System.out.println(list);

8 转为set集合

        Set<User> set = arrayList.stream()
                //中间操作,进行了一个排序的操作
                .collect(Collectors.toSet());//将处理完后的流转换为List类型的数据
        System.out.println("转换为一个Set的集合:");//set就是不重复
        System.out.println(set);

9 转为map

        Map<String, Integer> map = arrayList.stream()
                //中间操作,进行了一个排序的操作
                .collect(Collectors.toMap(User::getName, User::getAge));//将处理完后的流转换为List类型的数据
        System.out.println("转换为map的结果:");
        System.out.println(map);

10 转换为一个数组

        Object[] array = list1.stream().sorted().toArray();
        System.out.println(Arrays.toString(array));

11 取出最大值

        Integer max = Stream.of(2, 4, 3, 6, 1, 7, 5)
                //中间操作
                .sorted()   //自然排序
                //sorted的结果为 1,2,3,4,5,6,7
                //终端操作
                .max((o1, o2) -> {
                    return o1 - o2;
                })//max的返回值是一个Optional这样的对象中
                //再调用Optional中的get的这个方法,将值拿到就行了
                .get();
        System.out.println(max);

12 取出最小值

        Integer min = Stream.of(2, 4, 3, 6, 1, 7, 5)
                //中间操作
                .sorted()   //自然排序
                //sorted的结果为 1,2,3,4,5,6,7
                //终端操作
                .min((o1, o2) -> {
                    return o1 - o2;
                })//min和max一样同理
                .get();
        System.out.println(min);

13 返回总个数

        long count = Stream.of(2, 4, 3, 6, 1, 7, 5)
                //中间操作
                .sorted()   //自然排序
                //sorted的结果为 1,2,3,4,5,6,7

                //终端操作
                .count();//count返回的总共有多少个数据元素
        System.out.println(count);

15 求总和

        Integer reduce = Stream.of(2, 4, 3, 6, 1, 7, 5)
                //中间操作
                .sorted()   //自然排序
                //sorted的结果为 1,2,3,4,5,6,7
                //终端操作
                .reduce((o1, o2) -> {
                    return o1 + o2;
                })//count返回的总共有多少个数据元素
                .get();
        System.out.println(reduce);

16 anyMatch:只要流中有一个元素满足条件则返 回 true,否则返回 false

        boolean anyMatch = Stream.of(2, 4, 3, 6, 1, 7, 5)
                //中间操作
                .sorted()   //自然排序
                //sorted的结果为 1,2,3,4,5,6,7

                //终端操作
                .anyMatch((e) -> {
                    return e > 3;
                });//表示流中的元素只要有一个大于3就返回true
        System.out.println("angMatch:" + anyMatch);

17 allMatch: 当流中每个元素都符合条件时才返 回 true,否则返回 false

        boolean allMatch = Stream.of(2, 4, 3, 6, 1, 7, 5)
                //中间操作
                .sorted()   //自然排序
                //sorted的结果为 1,2,3,4,5,6,7
                //终端操作
                .allMatch((e) -> {
                    return e > 3;
                });//表示流中的元素全部都大于3才返回true
        System.out.println("allMatch:" + allMatch);

18 取出第一个元素

         Integer findFirst = Stream.of(2, 4, 3, 6, 1, 7, 5)
                //中间操作
                .sorted()   //自然排序
                //sorted的结果为 1,2,3,4,5,6,7
                //终端操作
                .findFirst()    //findFirst的终端操作也用的是Optional的对象
                .get();         //要对数据进行输出,所以也要用的get的方法
        System.out.println("findFirst:" + findFirst);

19 数组与list的相互转换

        int[] array1 = {1, 2, 5, 5, 5, 5, 6, 6, 7, 2, 9, 2};
        /* int[] 转 list */
        //方法一:需要导入commons-lang3依赖  ArrayUtils.toObject把int转为Integer
        List<Integer> list3 = Arrays.asList(ArrayUtils.toObject(array1));
        //方法二:java8及以上版本 boxed()转为Integer
        List<Integer> list4 = Arrays.stream(array1).boxed().collect(Collectors.toList());
        System.out.println(list3);
        System.out.println(list4);
        System.out.println();

        /* list 转 int[]*/
        //方法一:
        Integer[] intArr = list3.toArray(new Integer[list3.size()]);
        //方法二:java8及以上版本
        int[] intArr1 = list3.stream().mapToInt(Integer::valueOf).toArray();
        System.out.println(Arrays.toString(intArr));
        System.out.println(Arrays.toString(intArr1));

        //数组为Integer类型
        Integer[] array2 = {1, 2, 5, 5, 5, 5, 6, 6, 7, 2, 9, 2};
        List<Integer> list5 = Arrays.asList(array2);
        System.out.println(list5);

20 name为key,age为value,如果key重复,取后一个v2值

userMap = userList.stream().collect(Collectors.toMap(User::name, User-> User, (v1, v2) -> v2));

21 升序排序

// 根据age排序 (正序)
list = list.stream().sorted(Comparator.comparing(User::getAge)).collect(Collectors.toList());
//输出
//[User(name=小南, age=20, phone=18335888888), User(name=小南, age=21, phone=18335888888), User(name=小南, age=22, phone=18335888888), User(name=小南, age=23, phone=18335888888)]
// (倒序)
list = list.stream().sorted(Comparator.comparing(User::getAge).reversed()).collect(Collectors.toList());
//输出
//[User(name=小南, age=23, phone=18335888888), User(name=小南, age=22, phone=18335888888), User(name=小南, age=21, phone=18335888888), User(name=小南, age=20, phone=18335888888)]
//如果排序字段为空将空的某一条默认排到开头还是结尾
//放到结尾
list = list.stream().sorted(Comparator.comparing(User::getAge,Comparator.nullsLast(Integer::compare).reversed())).collect(Collectors.toList());
//放到开头
list = list.stream().sorted(Comparator.comparing(User::getAge,Comparator.nullsFirst(Integer::compare).reversed())).collect(Collectors.toList());

22 降序排序

stream流降序
list.stream().sorted(Comparator.reverseOrder())
stream流根据某一字段降序
list.stream().sorted(Comparator.comparing(User::getAge).reversed())

23 排序并去重

//需要使用文章上面的工具类StreamUtils
list = list.stream().sorted(Comparator.comparing(User::getAge,Comparator.nullsLast(Integer::compare).reversed())).filter(StreamUtils.distinctByKey(User :: getName)).collect(Collectors.toList());

24 根据两个字段排序

list.stream().sorted(Comparator.comparing(User::getAge).thenComparing(User::getName)).collect(Collectors.toList());

25 根据中文字段排序

list.parallelStream().sorted(Comparator.comparing(User::getChName,Collator.getInstance(Locale.CHINA))).collect(Collectors.toList());

26 通过对象里面的某个字段进行分组

Map<Long, List<Keyword>> keywords = keywordService.getKeywordsByPaperId(paperIds).stream().collect(Collectors.groupingBy(Keyword::getPaperId));

27 通过对象里面的某个字段映射为Map

Map<String, Item> itemMap = itemList.stream().filter(t -> StringUtils.isNotEmpty(t.getCode())).collect(Collectors.toMap(Item::getCode, Function.identity()));

总结

  • 有用到新的就来更新

作为程序员第 163 篇文章,每次写一句歌词记录一下,看看人生有几首歌的时间,wahahaha …
Java常用的stream流操作,附源码Java常用的stream流操作,附源码Java常用的stream流操作,附源码

Lyric: 包括像猫的狗

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/110712.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!