首页 > 编程语言 >Java 8 Stream 流的常用方法总结

Java 8 Stream 流的常用方法总结

时间:2023-12-12 21:06:01浏览次数:48  
标签:总结 Java Stream stream Arrays List words asList

Java 8 Stream 流的常用方法总结

Java 8 引入了一个新的 API:Stream API,它允许我们以声明式的方式处理数据集合。Stream API 提供了一系列强大的方法,可以帮助我们更简洁、高效地处理数据。本文将总结 Java 8 Stream 流的常用方法,并提供相应的代码示例。

1. 创建 Stream

首先,我们需要了解如何创建一个 Stream。以下是几种创建 Stream 的方法:

1.1 从集合创建

List<String> list = Arrays.asList("A", "B", "C");
Stream<String> stream = list.stream();

1.2 从数组创建

String[] array = {"A", "B", "C"};
Stream<String> stream = Arrays.stream(array);

1.3 生成 Stream

Stream<Integer> stream = Stream.generate(() -> new Random().nextInt());
stream.limit(5).forEach(System.out::println);

2. 中间操作

中间操作是在 Stream 上执行的操作,它们不会生成最终结果,而是产生一个新的 Stream。这些操作通常具有无状态性,即多次调用同一个中间操作可能会产生不同的结果。

2.1 filter

filter(Predicate<T> predicate) 方法根据给定的谓词过滤元素。例如,筛选出列表中的偶数:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
List<Integer> evenNumbers = numbers.stream()
                                 .filter(n -> n % 2 == 0)
                                 .collect(Collectors.toList());

2.2 map

map(Function<T, R> mapper) 方法将 Stream 中的每个元素映射到另一个元素。例如,将列表中的每个字符串转换为大写:

List<String> words = Arrays.asList("hello", "world");
List<String> upperCaseWords = words.stream()
                                 .map(String::toUpperCase)
                                 .collect(Collectors.toList());

2.3 peek

peek(Consumer<T> action) 方法在 Stream 中的每个元素上执行一个操作,但不会改变元素本身。例如,打印列表中的每个元素:

List<String> words = Arrays.asList("hello", "world");
words.stream()
     .peek(System.out::println)
     .collect(Collectors.toList());

2.4 distinct

distinct() 方法返回一个剔除重复元素的 Stream。例如,移除列表中的重复字符串:

List<String> words = Arrays.asList("hello", "world", "hello");
List<String> uniqueWords = words.stream()
                                 .distinct()
                                 .collect(Collectors.toList());

2.5 sorted

sorted() 方法对 Stream 中的元素进行排序。例如,对数字列表进行升序排序:

List<Integer> numbers = Arrays.asList(3, 1, 4, 1, 5, 9);
List<Integer> sortedNumbers = numbers.stream()
                                  .sorted()
                                  .collect(Collectors.toList());

2.6 limit

limit(long maxSize) 方法返回一个 Stream,其中包含最多 maxSize 个元素。例如,获取列表中的前三个元素:

List<String> words = Arrays.asList("A", "B", "C", "D", "E");
List<String> firstThreeWords = words.stream()
                                  .limit(3)
                                  .collect(Collectors.toList());

2.7 skip

skip(long n) 方法返回一个 Stream,跳过前 n 个元素。例如,跳过列表中的前两个元素:

List<String> words = Arrays.asList("A", "B", "C", "D", "E");
List<String> skipFirstTwoWords = words.stream()
                                     .skip(2)
                                     .collect(Collectors.toList());

可以配合limit实现分页

/**
         * //limit(n):获取n个元素
         * //skip(n):跳过n元素,配合limit(n)可实现分页
         */
        int currentPage = 1;//页数(必须大于等于1)
        int pageSize = 3;//每页数量
        List<String> pageData = stringList.stream().skip((currentPage - 1) * pageSize).limit(pageSize).
                collect(Collectors.toList());
        int count = stringList.size();//总数
        int pagecount = 0;//总页数
        int i = count % pageSize;
        if (i>0){
            pagecount = count / pageSize + 1;
        }else {
            pagecount = count / pageSize;
        }
        System.out.println("skip/limit配合分页数据:"+pageData);
        System.out.println("总数:"+count);
        System.out.println("总页数:"+pagecount);

2.8 groupingBy

groupingBy(Function<T, K> classifier) 方法根据给定的分类器对元素进行分组。例如,按字符串长度分组:

List<String> words = Arrays.asList("apple", "banana", "cherry", "date");
Map<Integer, List<String>> groupedWords = words.stream()
                                             .collect(Collectors.groupingBy(word -> word.length()));

一些复杂数据的排序和分组

List<Map<String,Object>> listMapData = new ArrayList<>();
        Map<String,Object> map = new HashMap<>();
        Map<String,Object> map2 = new HashMap<>();
        Map<String,Object> map3 = new HashMap<>();
        map.put("age",18);
        map.put("name","张三");
        map2.put("age",20);
        map2.put("name","李四");
        map3.put("age",18);
        map3.put("name","王五");
        listMapData.add(map);
        listMapData.add(map2);
        listMapData.add(map3);
        System.out.println("排序前:"+listMapData);
        //年龄排序 (会影响原数据)
        listMapData.sort((x,y)-> Integer.compare(Integer.valueOf(String.valueOf(x.get("age"))), Integer.valueOf(String.valueOf(y.get("age")))));
        //年龄排序 (数字排序)
        List<Map<String, Object>> aa = listMapData.stream().sorted((o1, o2) -> Integer.valueOf(String.valueOf(o1.get("age"))) - Integer.valueOf(String.valueOf(o2.get("age")))).collect(Collectors.toList());
        //姓名排序(字符串排序)
        List<Map<String, Object>> abc = listMapData.stream().sorted((o1, o2) -> Collator.getInstance(Locale.TRADITIONAL_CHINESE).compare(o1.get("name"), o2.get("name"))).collect(Collectors.toList());
        //实体类排序 两个字段排序参考
        System.out.println("年龄排序后:"+listMapData);
        System.out.println("年龄排序后:"+aa);
        System.out.println("姓名排序后:"+abc);

        /**
         * groupingBy分组
         */
        Map<Object, List<Map<String, Object>>> groupData = listMapData.stream().collect(Collectors.groupingBy(o -> o.get("age")));
        Map<Object, List<Map<String, Object>>> grouptwoData = listMapData.stream().collect(Collectors.groupingBy(o -> o.get("age")+"_"+o.get("name")));
        System.out.println("根据年龄分组后的数据:"+groupData);
        System.out.println("根据年龄+姓名分组后的数据:"+grouptwoData);

3. 终止操作

终止操作会产生一个结果,或者副作用。以下是一些常用的终止操作:

3.1 forEach

forEach(Consumer<T> action) 方法对 Stream 中的每个元素执行一个操作。例如,打印列表中的每个元素:

List<String> words = Arrays.asList("A", "B", "C");
words.stream().forEach(System.out::println);

3.2 count

count() 方法返回 Stream 中元素的数量。例如,获取列表中的元素个数:

List<String> words = Arrays.asList("A", "B", "C");
long wordCount = words.stream().count();

3.3 collect

collect(Collector<T, A, R> collector) 方法将 Stream 中的元素收集到一个集合中。例如,将列表中的元素收集到一个新的列表中:

List<String> words = Arrays.asList("A", "B", "C");
List<String> collectedWords = words.stream()
                                   .collect(Collectors.toList());

3.4 reduce

reduce(T identity, BinaryOperator<T> accumulator) 方法将 Stream 中的元素通过累加器进行累积,返回累积结果。例如,计算列表中所有数字的和:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream().reduce(0, Integer::sum);

3.5 min & max

min(Comparator<T> comparator)max(Comparator<T> comparator) 方法分别返回 Stream 中的最小值和最大值。例如,找到列表中的最小和最大字符串:

List<String> words = Arrays.asList("apple", "banana", "cherry");
Optional<String> minWord = words.stream().min(Comparator.comparing(String::length));
Optional<String> maxWord = words.stream().max(Comparator.comparing(String::length));

3.6 anyMatch & allMatch

anyMatch(Predicate<T> predicate)allMatch(Predicate<T> predicate) 方法分别检查 Stream 中是否存在至少一个元素满足给定谓词,以及 Stream 中的所有元素是否都满足给定谓词。例如,检查列表中是否有字符串长度大于 5,以及所有字符串长度是否都大于 5:

List<String> words = Arrays.asList("apple", "banana", "cherry");
boolean anyLongWord = words.stream().anyMatch(word -> word.length() > 5);
boolean allLongWords = words.stream().allMatch(word -> word.length() > 5);

结论

Java 8 的 Stream API 提供了一种简洁、高效的方式来处理数据集合。通过掌握这些常用方法,我们可以更好地利用 Stream API 解决实际问题。

标签:总结,Java,Stream,stream,Arrays,List,words,asList
From: https://blog.51cto.com/u_16433912/8790253

相关文章

  • JavaScript 中栈与堆的区别
    每种编程语言都具有内建的数据类型,但它们的数据类型常有不同之处,使用方式也很不一样,比如C语言在定义变量之前,就需要确定变量的类型。在声明变量之前需要先定义变量类型。我们把这种在使用之前就需要确认其变量数据类型的称为静态语言。相反地,我们把在运行过程中需要检查数据类型......
  • 12/12每日总结
    最短路径BFS求无权图的单源最短路径简介直接进行广度优先遍历使用两个数组,一个记录最短路径值,一个记录到这个顶点的直接前驱只能用无权图迪杰斯特拉算法简介dijkstra算法是一种一步一步找出最短路径的方法,核心思路就是从初始点开始,一步一步从已确定路径中选取最短的路径作为新的最......
  • 数仓项目总结
    数仓项目总结一、数据采集数据从哪里来的?一般在实际开发中,是业务开发端在业务系统程序中,植入一些收集事件数据的SDK(工具代码),进行各种事件数据的收集,埋点数据可以植入到业务系统的前端程序或者后端程序中。我们作为大数据开发,只需要提出数据埋点需求,对具体实现技术仅作基本了......
  • 无涯教程-Java Access Modifiers函数
    Java提供了许多访问修饰符来设置类,变量,方法和构造函数的访问级别。四个访问级别是-default(默认):对当前包可见,不需要修饰符。private(私有):当前类可见。public(公共):都可见。protected(受保护):对当前包和所有子类可见。默认访问修饰符默认访问修饰符意味着我们......
  • 无涯教程-Java - Singleton Classes函数
    Singleton的目的是控制对象的创建,将对象的数量限制为一个。由于只有一个Singleton实例,因此Singleton的任何实例字段在每个类中只会出现一次,就像static字段一样。单例通常控制对资源的访问,例如数据库连接或Socket。例如,如果您仅对数据库的一个连接拥有许可证,或者JDBC驱动......
  • 关于Rust的简单总结(一)
    0.前言这是一个关于Rust的简单总结。(待续)资料学习网址:学习Rust-Rust程序设计语言(rust-lang.org)官网:Rust程序设计语言(rust-lang.org)Rust介绍[[Rust]]程序设计语言的本质实际在于 赋能(empowerment):无论你现在编写的是何种代码,Rust能让你在更为广泛的编程......
  • java文件的上传与下载
    1、文件上传下载1.1文件上传什么是文件上传?要将客户端(浏览器)大数据存储到服务器端,不将数据直接存储到数据库中,而是要将数据存储到服务器所在的磁盘上,这就要使用文件上传。为什么使用文件上传?通过文件上传,可以将浏览器端的大数据直接保存到服务器端。不将数据保存到数据库中......
  • 项目经理的年终总结没写好,一年全白干
    项目经理年终吐槽大会:又到年底了,办公室的项目经理们好不容易能聚在一起,大家在交流工作时,对这一年的工作状态简要吐槽了几句。每一句都堪称经典,但无不透露出各种心酸。a)     项目经理小王:感情状态——继续单身,根本没空谈恋爱;身材体重——过劳肥。b)     项目经理小刘:每......
  • Java Spring Boot 拦截器的使用小结
    很多时候,我们在开发项目中,总是希望在接口中,尽量进行业务处理,其余的事项交给其他组件来处理,比如:登录验证日志记录接口性能在SpringBoot中,正如大多数框架一样,可以用到拦截件进行处理,不管叫中间件还是拦截件,总之都是为了让我们更好的专注于业务,解耦功能。我们看看SpringB......
  • 《Effective Java》阅读笔记-第五章
    EffectiveJava阅读笔记第五章泛型第26条不要使用原生类型随着泛型的普及,这条没什么可说的。如果不知道具体类型,可以使用<?>来代替。第27条消除unchecked警告原生类型到泛型转换时,编译会有警告,可以使用@SuppressWarnings("unchecked")来消除警告。并且应该在尽可......