Java 8 Stream流的几种常见使用

中间操作、终止操作

只有中间操作没有终止操作的话,这些操作不会立即执行,也就是不会立即对元素进行处理,而是返回一个新的 Stream 对象,这个新的 Stream 对象会在遇到终止操作时才会执行中间操作中定义的逻辑。

简单来说,中间操作返回的是一个“惰性求值”的 Stream 对象,只有在遇到终止操作时才会触发实际的计算,这种方式可以提高计算效率。

中间操作和终止操作分别有哪些?

  • 中间操作:
    • filter、limit、skip、distinct、sorted
    • map
    • parallel
  • 终止操作
    • forEach、sum、min、max、count、average
    • anyMatch、allMatch、noneMatch
    • reduce、collect

filter

使用 filter 方法可以根据指定的条件过滤出符合条件的元素。

ArrayList<String> list = new ArrayList<>();
list.add("《日日是好日》");
list.add("《三国演义》");
list.add("《孙子兵法》");
list.add("《小狗钱钱》");
Stream<String> stream = list.stream().filter(element -> element.contains("日"));
stream.forEach(System.out::println);
// 输出:《日日是好日》

limit

limit 方法可以截取指定数量的元素,返回一个新的流。

List<Integer> numbers = Arrays.asList(1, 2, 3, 2, 5);
Stream<Integer> distinct = numbers.stream().limit(3);
distinct.forEach(System.out::println);
// 输出:
// 1
// 2
// 3

skip

skip 方法可以跳过指定数量的元素。

List<Integer> numbers = Arrays.asList(8, 2, 3, 2, 5);
Stream<Integer> skip = numbers.stream().skip(2);
skip.forEach(System.out::println);
// 输出:
// 3
// 2
// 5

distinct

使用 distinct 方法可以去除流中重复的元素。

List<Integer> numbers = Arrays.asList(1, 2, 3, 2, 5);
Stream<Integer> distinctNumbers = numbers.stream().distinct();
distinctNumbers.forEach(System.out::println);
// 输出:
// 1
// 2
// 3
// 5

sorted

使用 sorted 方法可以对流中的元素进行排序。

int[] numbers = {5, 8, 1, 3, 9};
IntStream sortedNumbers = Arrays.stream(numbers).sorted();
sortedNumbers.forEach(System.out::println);
// 输出:
// 1
// 3
// 5
// 8
// 9

对流中的对象进行排序,需要实现 Comparable 接口或者使用 Comparator 接口。

1、实现 Comparable 接口

package com.qf.cmf.javabase.stream;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

class Person implements Comparable<Person> {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public int compareTo(Person o) {
        return Integer.compare(this.age, o.age);
    }
}

public class StreamSortedExample {
    public static void main(String[] args) {
        List<Person> people = new ArrayList<>();
        people.add(new Person("A", 20));
        people.add(new Person("B", 25));
        people.add(new Person("C", 18));
        people.add(new Person("D", 30));

        // 使用Comparable接口进行排序
        Collections.sort(people);
        System.out.println(people);
    }
}
// 输出:
// [Person{name='C', age=18}, Person{name='A', age=20}, Person{name='B', age=25}, Person{name='D', age=30}]

2、 Comparator 接口

package com.qf.cmf.javabase.stream;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

public class StreamSortedExample {
    public static void main(String[] args) {
        List<Person> people = new ArrayList<>();
        people.add(new Person("A", 20));
        people.add(new Person("C", 25));
        people.add(new Person("B", 18));
        people.add(new Person("D", 30));

        // 使用Comparator接口进行排序
        people.stream().sorted(Comparator.comparing(Person::getName)).forEach(p -> System.out.println(p.getName() + " " + p.getAge()));
    }
}
// 输出:
// A 20
// B 18
// C 25
// D 30

map

使用 map 方法可以将一个流中的元素按照指定的方式进行转换,生产一个新的流。

ArrayList<String> list = new ArrayList<>();
list.add("《日日是好日》");
list.add("《三国演义》");
list.add("《孙子兵法》");
list.add("《小狗钱钱》");
Stream<Integer> stream = list.stream().map(String::length);
stream.forEach(System.out::println);
// 输出:
// 7
// 6
// 6
// 6

forEach

forEach 方法可以用来遍历 Stream 中的每一个元素,它的语法如下:

void forEach(Consumer<? super T> action)

其中,action 表示对每个元素要执行的操作,它是一个 Consumer 接口的实例。

List<String> list = Arrays.asList("Java", "Python", "JavaScript", "C++");

// 使用 forEach() 方法遍历 Stream 中的每一个元素
list.stream().forEach(System.out::println);

// 输出:
// Java
// Python
// JavaScript
// C++

sum、min、max、count、average

使用 sum、min、max、count、average 等方法可以对流中的元素进行统计

sum 求和

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream().mapToInt(Integer::intValue).sum();
System.out.println(sum); // 输出 15

min 求最小值

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int min = numbers.stream().mapToInt(Integer::intValue).min().orElse(0);
System.out.println(min); // 输出 1

求最大值

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int max = numbers.stream().mapToInt(Integer::intValue).max().orElse(0);
System.out.println(max); // 输出 5

统计元素个数

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
long count = numbers.stream().count();
System.out.println(count); // 输出 5

求平均值

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
double average = numbers.stream().mapToInt(Integer::intValue).average().orElse(0);
System.out.println(average); // 输出 3.0

anyMatch、allMatch、noneMatch

使用 anyMatch、allMatch、noneMatch 等方法可以判断流中的元素是否符合指定的条件。

anyMatch:返回一个 boolean 值,表示 Stream 中是否存在至少一个元素符合指定的条件。

allMatch:返回一个 boolean 值,表示 Stream 中的所有元素是否都符合指定的条件。

noneMatch:返回一个 boolean 值,表示 Stream 中是否不存在任何一个元素符合指定的条件。

ArrayList<String> list = new ArrayList<>();
list.add("《日日是好日》");
list.add("《三国演义》");
list.add("《孙子兵法》");
list.add("《小狗钱钱》");
boolean  anyMatchFlag = list.stream().anyMatch(element -> element.contains("技"));
boolean  allMatchFlag = list.stream().allMatch(element -> element.length() > 1);
boolean  noneMatchFlag = list.stream().noneMatch(element -> element.endsWith("术"));
// 输出
// false
// true
// true

reduce

reduce 函数的语法如下:

T reduce(BinaryOperator<T> accumulator)

使用 reduce 方法可以将流中的元素按照指定的方式进行归约,生成一个新的值。

Integer[] ints = {0, 1, 2, 3};
List<Integer> list = Arrays.asList(ints);

Optional<Integer> optional = list.stream().reduce((a, b) -> a + b);
Optional<Integer> optional1 = list.stream().reduce(Integer::sum);
System.out.println(optional.orElse(0));
System.out.println(optional1.orElse(0));
// 输出:
// 6
// 6

int reduce = list.stream().reduce(6, (a, b) -> a + b);
System.out.println(reduce);

int reduce1 = list.stream().reduce(6, Integer::sum);
System.out.println(reduce1);
// 输出:
// 12
// 12

reduce 可以设定初始值,如果设定了的话初始值也会加上运算。

collect

使用 collect 方法可以将流中的元素收集到一个集合中。

ArrayList<String> list = new ArrayList<>();
list.add("《日日是好日》");
list.add("《三国演义》");
list.add("《孙子兵法》");
list.add("《小狗钱钱》");
List<Integer> list1 = list.stream().map(String::length).collect(Collectors.toList());
List<String> list2 = list.stream().collect(Collectors.toCollection(ArrayList::new));
List<String> list3 = list.stream().collect(Collectors.toList());
String list4 = list.stream().collect(Collectors.joining(", ")).toString();
System.out.println(list1);
System.out.println(list2);
System.out.println(list3);
System.out.println(list4);
// 输出:
// [7, 6, 6, 6]
// [《日日是好日》, 《三国演义》, 《孙子兵法》, 《小狗钱钱》]
// [《日日是好日》, 《三国演义》, 《孙子兵法》, 《小狗钱钱》]
// 《日日是好日》, 《三国演义》, 《孙子兵法》, 《小狗钱钱》

总结

Stream 是非常强大的,感兴趣可以深入去学习。


“行动是治愈恐惧的良药,而犹豫拖延将不断滋养恐惧。"

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值