List中Stream流操作

准备

public class Person {
    private String name;
    private int age;
}

public class Test {
    public static void main(String[] args) {
        List<Person> list = new ArrayList<>();
        list.add(new Person("豆豆",18));
        list.add(new Person("锴锴",16));
        list.add(new Person("哈哈",17));
    }
}
stream() / parallelStream() 最常用到的方法,将集合转换为流
//stream 将集合转换为流
list.stream();
// parallelStream()是并行流方法,能够将数据执行并行操作
list.parallelStream();
filter(T -> boolean) 保留 boolean 为 true 的元素
//filter(T -> boolean)  保留Boolean为true的元素
List list1 = list.stream().filter(person -> person.getAge() == 18).collect(toList());
System.out.println("filter:对元素进行过滤"+list1);

filter:对元素进行过滤[Person{name='豆豆', age=18}]
distinct()

去除重复元素,这个方法是通过类的 equals 方法来判断两个元素是否相等的
如例子中的 Person 类,需要先定义好 equals 方法,不然类似[Person{name=‘jack’, age=20}, Person{name=‘jack’, age=20}] 这样的情况是不会处理的

sorted() / sorted((T, T) -> int)

如果流中的元素的类实现了 Comparable 接口,即有自己的排序规则,那么可以直接调用 sorted() 方法对元素进行排序,如 Stream
反之, 需要调用 sorted((T, T) -> int) 实现 Comparator 接口

List list2 = list.stream()
                .sorted((p1,p2)-> p1.getAge() - p2.getAge())
                .collect(toList());
System.out.println("sorted:对元素进行排序"+list2);
//可以简化为
list2 = list.stream()
            .sorted(Comparator.comparingInt(Person::getAge))
            .collect(toList());

sorted:对元素进行排序[Person{name='锴锴', age=16}, Person{name='哈哈', age=17}, Person{name='豆豆', age=18}]
limit(long n) 返回前 n 个元素
List list3 = list.stream()
                .limit(2)
                .collect(toList());
System.out.println("limit:返回前n个元素"+list3);

limit:返回前n个元素[Person{name='豆豆', age=18}, Person{name='锴锴', age=16}]
skip(long n) 去除前 n 个元素
List list4 = list.stream()
                .skip(2)
                .collect(toList());
System.out.println("skip:去除前n个元素"+list4);

skip:去除前n个元素[Person{name='哈哈', age=17}]

tips:

用在 limit(n) 前面时,先去除前 m 个元素再返回剩余元素的前 n 个元素
limit(n) 用在 skip(m) 前面时,先返回前 n 个元素再在剩余的 n 个元素中去除 m 个元素

map(T -> R) 将流中的每一个元素 T 映射为 R(类似类型转换)

list5 里面的元素为 list 中每一个 Person 对象的 name 变量

List list5 = list.stream()
                .map(Person::getName)
                .collect(toList());
System.out.println("map:将流中的每个元素T映射为R"+list5);

map:将流中的每个元素T映射为R[豆豆, 锴锴, 莉莉]
flatMap(T -> Stream) 将流中的每一个元素 T 映射为一个流,再把每一个流连接成为一个流
List<String> lista = new ArrayList<>();
lista.add("aaa bbb ccc");
lista.add("ddd eee fff");
lista.add("ggg hhh iii");

lista = lista.stream().map(s -> s.split(" ")).flatMap(Arrays::stream).collect(toList());
System.out.println(lista);

[aaa, bbb, ccc, ddd, eee, fff, ggg, hhh, iii]

上面例子中,我们的目的是把 List 中每个字符串元素以" "分割开,变成一个新的 List。
首先 map 方法分割每个字符串元素,但此时流的类型为 Stream<String[ ]>,因为 split 方法返回的是 String[ ] 类型;所以我们需要使用 flatMap 方法,先使用Arrays::stream将每个 String[ ] 元素变成一个 Stream 流,然后 flatMap 会将每一个流连接成为一个流,最终返回我们需要的 Stream

anyMatch(T -> boolean)

流中是否有一个元素匹配给定的 T -> boolean 条件
是否存在一个 person 对象的 age 等于 18:

boolean b = list.stream().anyMatch(person -> person.getAge() == 18);
allMatch(T -> boolean)

流中是否所有元素都匹配给定的 T -> boolean 条件

noneMatch(T -> boolean)

流中是否没有元素匹配给定的 T -> boolean 条件

findAny() 和 findFirst()

findAny():找到其中一个元素 (使用 stream() 时找到的是第一个元素;使用 parallelStream() 并行时找到的是其中一个元素)
findFirst():找到第一个元素

reduce((T, T) -> T) 和 reduce(T, (T, T) -> T)

用于组合流中的元素,如求和,求积,求最大值等

计算年龄总和:
int sum = list.stream().map(Person::getAge).reduce(0, (a, b) -> a + b);
与之相同:
int sum = list.stream().map(Person::getAge).reduce(0, Integer::sum);

count() 返回流中元素个数,结果为 long 类型

forEach() 返回结果为 void

​ 可以把Java8的流看作数据集迭代器。他们支持两种类型的操作:中间操作(e.g. filter,map)和终端操作(如count,findFirst,forEach,reduce),中间操作可以连接起来,将一个流转换为另一个流,这些操作不会消耗流,其目的是建立一个流水线。与此相反,终端操作会消耗流,产生一个最终结果。collect就是一个归约操作,就像reduce一样可以就收各种方法作为参数,将流中的元素累积成一个汇总的结果。具体的做法是通过定义新的Collector接口来定义的。

把Stream的元素拼起来
//直接拼接
String join1 = list.stream().map(Person::getName).collect(Collectors.joining());
//连接拼接
String join2 = list.stream().map(Person::getName).collect(Collectors.joining(","));
toList
List<String> names = listream().map(Person::getName).collect(toList());
toSet
Set<String> names = list.stream().map(Person::getName).collect(Collectors.toSet());
toMap
Map<String,Person> persons = list.stream().collect(toMap(Person::getName,p -> p));
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值