Java Stream 最全操作用法合集

这篇具有很好参考价值的文章主要介绍了Java Stream 最全操作用法合集。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Java 8 引入了Stream流的操作,让我们在开发的过程中感受到了很多的便利,小宋我也花时间总结了下关于Stream的堪称最全的使用方法,话不多说,直接放大招。

流(stream)的类型

Java 8提供了两种方式去创建流:

1、stream

stream是串行的,可以理解为它的执行是按顺序执行的。

2、parallelStream

parallelStream是并行的,可以理解为它的执行不是按顺序执行的,它的原理采用了分治的原理去实现,可以点击查看Fork/Join,我就不多做解释啦,并行是为了充分利用CPU的性能,如果CPU不太行的话,还是不用吧,并行执行会有不确定性,而且不是线程安全的,大家用的时候要多注意了。

流(stream)的创建种类

方法 举例
Collectionstream()方法或者parallelStream() Arrays.asList(1,2,3).stream()
使用流的静态方法 比如Stream.of(Object[]), IntStream.range(int, int) 或者 Stream.iterate(Object, UnaryOperator),如Stream.iterate(0, n -> n * 2),或者generate(Supplier s)如Stream.generate(Math::random)。
文件中获得行的流 BufferedReader.lines()
Files类的操作路径的方法 如list、find、walk等
随机数 Random.ints()
Arrays.stream(Object[])方法 Arrays.stream(new int[]{1,2,3})
其它一些类提供了创建流的方法 如BitSet.stream(),Pattern.splitAsStream(java.lang.CharSequence), 和 JarFile.stream()

流(stream)的中间操作

1. (常用)map()

map是stream中非常常用的一个方法,它用于映射每个元素到对应的结果里面,可以让你提取对象中的某一个属性或者转化成其它的对象,下面有几个例子可以用作参考。

例1-获取对应的平方数
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()是去掉重复的值。
例2-将用户的名字提取出来转成字符串集

首先定义两个对象,如下

@Data
public class StaffPublic {

    private String name;//名称

    private Integer age;//年龄

    private String extra;//额外信息

    public Staff(String name, Integer age, String extra) {
        this.name = name;
        this.age = age;
        this.extra= extra;
    }
}
@Data
public class Staff {

    private String name;//名称

    private Integer age;//年龄

    private String sex;//性别

    public Staff(String name, Integer age, String sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }
}
List<Staff> staff = new ArrayList<>();
staff.add(new Staff("ricky",30,"man"));
staff.add(new Staff("jack",27,"man"));
staff.add(new Staff("lawrence",33,"woman"));
List<String> collect = staff.stream().map(x -> x.getName()).collect(Collectors.toList());
System.out.println(collect); 
//输出 [ricky, jack, lawrence]
例3-将结果转成另一个对象
List<StaffPublic> result = staff.stream().map(temp -> {
            StaffPublic obj = new StaffPublic();
            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());
System.out.println(result);
//输出
[
    StaffPublic{name='ricky', age=30, extra='this field is for ricky only!'},
    StaffPublic{name='jack', age=27, extra='null'},
    StaffPublic{name='lawrence', age=33, extra='null'}
]

2. (常用)filter()

filter 主要用于通过设置的条件过滤出符合的元素,类似于一个过滤器。

例1-获取空字符串的数量
List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
// 获取空字符串的数量
long count = strings.stream().filter(string -> string.isEmpty()).count();
// 输出结果:2
例2-查找身高在1.8米及以上的男生
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代表男生

3. limit()

limit 对一个Stream进行截断操作,获取其前N个元素。如果原Stream中包含的元素个数小于N,那就获取其所有的元素,这是一个short-circuiting 操作。

例1-用于获取指定数量的流-1
Random random = new Random();
random.ints().limit(3).forEach(System.out::println);
// 输出结果
93148391
-108910530
-654413184
例2-用于获取指定数量的流-2
List<String> strings = Arrays.asList("abc", "dd", "bc", "efg", "abcd","cc", "jkl");
strings.stream().limit(2).forEach(System.out::println);
//输出 abc dd

4. skip()

skip 可以对流进行一个跳过操作,可以通过自定义的数值N去跳过前N个元素。

例1-跳过前3个元素
List<String>strings = Arrays.asList("abc", "dd", "bc", "efg", "abcd","cc", "jkl");
strings.stream().skip(3).forEach(System.out::println);
// 输出结果
efg
abcd
cc
jkl

5. distinct()

distinct 是对流进行一个去重的操作,是通过元素的hashcode()和equals()去判断两个元素是否一致的,这样我们在使用对象去重的时候,可以通过重写它的hascode和equals方法就可以达到我们想要的效果了。

例1-字符串数组去重
List<String>strings = Arrays.asList("abc", "dd", "bc", "abc", "bc","cc", "dd");
strings.stream().distinct().forEach(System.out::println);
// 输出结果
abc
dd
bc
cc

6. peek()

peek 生成一个包含原Stream的所有元素的新Stream,同时会提供一个消费函数(Consumer实例),新Stream每个元素被消费的时候都会执行给定的消费函数,peek主要被用在debug用途。

例1-实例
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

7. sorted()

sorted 是对流进行一个排序操作。

  • sorted 自然排序(Comparable)
  • sorted(Comparator com) 定制排序(Comparator)
例1-sorted自然排序
List<String> list = Arrays.asList("cc","aa","dd","bb");
        list.stream().sorted().forEach(System.out::println);
//输出
aa
bb
cc
dd
例2-sorted自然排序逆序
List<String> list = Arrays.asList("cc","aa","dd","bb");
        list.stream().sorted(Comparator.reverseOrder()).forEach(System.out::println);
//输出
dd
cc
bb
aa
例3-sorted定制排序
@Data
@AllArgsConstructor
public class Employee {
    private String name;
    private Integer age;
}
// 初始化参数
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));
list.stream().sorted(Comparator.comparingInt(Employee::getAge)).forEach(System.out::println);
// 输出
Employee(name=孙七, age=18)
Employee(name=王五, age=25)
Employee(name=李四, age=28)
Employee(name=张三, age=33)
Employee(name=赵六, age=40)
例4-sorted定制排序逆序
list.stream().sorted(Comparator.comparingInt(Employee::getAge).reversed()).forEach(System.out::println);
//输出
Employee(name=赵六, age=40)
Employee(name=张三, age=33)
Employee(name=李四, age=28)
Employee(name=王五, age=25)
Employee(name=孙七, age=18)

流(stream)的终止操作

1.(常用)collect()

collect 方法的功能是将 Stream 中数据转换为最终的结果

例1-基础用法
List list= Arrays.asList("a", "b", "c", "d");

List collect =list.stream().map(String::toUpperCase).collect(Collectors.toList());
System.out.println(collect); 
//输出
[A, B, C, D]

数组所有元素,按某种规律计算:
List num = Arrays.asList(1,2,3,4,5);
List collect1 = num.stream().map(n -> n * 2).collect(Collectors.toList());
System.out.println(collect1); 
//输出
[2, 4, 6, 8, 10]
例2-转换不同类型
Stream<String> stream = Stream.of("hello", "world", "helloworld");
//转成ArrayList
ArrayList<String> list = stream.collect(Collectors.toCollection(ArrayList::new));
//转成TreeSet
TreeSet<String> treeSet = stream.collect(Collectors.toCollection(TreeSet::new));
例3-拼接字符串
Stream<String> stream = Stream.of("hello", "world", "helloworld");
        String s = stream.collect(Collectors.joining(","));
        System.out.println(s);
//输出
hello,world,helloworld
例4-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);
//输出结果
张三,李四,王五,赵六,孙七
例5-Collectors.minBy 比较取小
Employee employee = list.stream().collect(Collectors.minBy(Comparator.comparingInt(Employee::getAge))).get();
System.out.println(employee);
//输出结果
Employee(name=孙七, age=18)
例6-Collectors.maxBy 比较取大
Employee employee = list.stream().collect(Collectors.maxBy(Comparator.comparingInt(Employee::getAge))).get();
System.out.println(employee);
//输出结果
Employee(name=赵六, age=40)
例7-Collectors.summarizingInt 年龄求和,此外还有summarizingDouble与summarizingLong,用法一致。
long sum = list.stream().collect(Collectors.summarizingInt(Employee::getAge)).getSum();
System.out.println(sum);
//输出结果
144
例8-Collectors.averagingInt 年龄求平均值,此外还有averagingDouble与averagingLong,用法一致。
Double avgAge = list.stream().collect(Collectors.averagingInt(Employee::getAge));
System.out.println(avgAge);
//输出结果
28.8
例9-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)
例10-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)
例11-(常用)Collectors.toMap 将结果转换成Map,可能会导致key重复的情况,需自行配置规则防止重复key报错。
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

2.(常用)forEach()

迭代流中的每一个数据,等同于for循环

Random random = new Random();
random.ints().limit(10).forEach(System.out::println);

List<String> items = Arrays.asList("a","b","c","d","e");
items.forEach(item->System.out.println(item));
//输出 a,b,c,d,e

3.find相关的操作

  • findAny查找任何一个就返回 Optional
List<String> strings = Arrays.asList("abc", "dd", "DD", "dd", "abcd","cc", "jkl");
String result = strings.stream().filter(str -> str.equals("dd"))
                .findAny()
                .orElse(null);
System.out.println(result);
//输出 dd
  • findFirst查找到第一个就返回 Optional
List<String> strings = Arrays.asList("abc", "dd", "DD", "dd", "abcd","cc", "jkl");
String result = strings.stream().filter(str -> str.equals("dd"))
                .findFirst()
                .orElse(null);
System.out.println(result);
//输出 dd
  • anyMatch匹配上任何一个则返回Boolean
List<String> strings = Arrays.asList("abc", "dd", "DD", "dd", "abcd","cc", "jkl");
Boolean result = strings.stream().anyMatch(str -> str.equals("dd"));
System.out.println(result);
//输出 true
  • allMatch匹配所有的元素则返回Boolean
List<String> strings = Arrays.asList("abc", "dd", "DD", "dd", "abcd","cc", "jkl");
Boolean result = strings.stream().allMatch(str -> str.equals("dd"));
System.out.println(result);
//输出 false
  • noneMatch检查在所需位置是否没有带有必需字符的元素,返回Boolean
List<String> strings = Arrays.asList("abc", "dd", "DD", "dd", "abcd","cc", "jkl");
Boolean result = strings.stream().noneMatch(str -> str.equals("ff"));
System.out.println(result);
//输出 true

4.reduce()

它可以把一个Stream的所有元素按照聚合函数聚合成一个结果文章来源地址https://www.toymoban.com/news/detail-592737.html

// 0代表初始值 如果不传0 则使用第一个元素作为初始值,acc是计算值,n 是每个元素
int sum = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9).reduce(0, (acc, n) -> acc + n);
System.out.println(sum); // 45

//不传初始值的情况下,返回的是Optional类型的结果
List<Integer> numList = Arrays.asList(1,2,3,4,5);
Optional<Integer> result = numList.stream().reduce((a, b) -> a + b);
System.out.println(result.get());

到了这里,关于Java Stream 最全操作用法合集的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java stream流中peek用法详解

    在Java中,Stream是一种用于处理集合数据的强大工具。它提供了一种函数式编程的方式来对数据进行操作和转换。Stream中的 peek 方法是一种非终端操作,它允许你在流的每个元素上执行一个操作,而不会改变流的内容。 peek 方法的语法如下: 其中, action 是一个接收一个元素并

    2024年02月05日
    浏览(51)
  • Java中Stream流式计算的用法详解

    在Java 8之后,引入了Stream API,它是一个函数式编程的思想,其主要作用是将集合Stream化,可以使用一条语句对集合进行过滤、排序、统计等多种操作。接下来我们将详细介绍Java中Stream流式计算的用法。 Stream 接口是Java中定义的一个操作集合的高级抽象,它提供了大量的操作

    2024年02月01日
    浏览(59)
  • Java8中Stream详细用法大全

    Java 8 是一个非常成功的版本,这个版本新增的Stream,配合同版本出现的Lambda ,给我们操作集合(Collection)提供了极大的便利。Stream流是JDK8新增的成员,允许以声明性方式处理数据集合,可以把Stream流看作是遍历数据集合的一个高级迭代器。Stream 是 Java8 中处理集合的关键抽

    2023年04月08日
    浏览(80)
  • 【Java基础】Stream 流中 Collectors.toMap 的用法

    Collectors.toMap() 方法是把 List 转 Map 的操作 1.1、如果不是对象,是数组,怎么转成map? 按照规范来写的话,最好所有toMap,都要将这个异常提前考虑进去,不然有时候会报重复主键异常,这也是正例的写法,上面的属于反例的写法。 2.1、Collectors.toMap 有三个重载方法:  参数解

    2024年02月14日
    浏览(44)
  • Java stream 分组操作

    根据单/多字段分组 单字段分组可以直接使用指定字段,多字段分组则采用拼接Key的形式 单字段: 多字段: 多层级: 测试

    2024年02月15日
    浏览(42)
  • Java 8 Stream 流操作

    博主 默语带您 Go to New World. ✍ 个人主页—— 默语 的博客👦🏻 《java 面试题大全》 《java 专栏》 🍩惟余辈才疏学浅,临摹之作或有不妥之处,还请读者海涵指正。☕🍭 《MYSQL从入门到精通》数据库是开发者必会基础之一~ 🪁 吾期望此文有资助于尔,即使粗浅难及深广,亦

    2024年04月16日
    浏览(27)
  • java Stream去重操作

     1.根据对象的某个属性去重: 网上找的stream流去重方法,可以根据类的某个属性去重,这里记录一下 使用:

    2024年02月10日
    浏览(33)
  • java 8 stream流的19种用法,可应对大多数集合的处理场景

    java 8的Stream API是一种非常强大的集合处理工具,它提供了一种新的、高效的、声明式的方式来处理集合数据。下面我们就来看一下Java 8 Stream API的所有用法。 可以使用Stream.of()方法创建一个Stream: 也可以使用集合的stream()方法创建一个Stream: 可以使用filter()方法过滤Stream中的

    2023年04月08日
    浏览(77)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包