jdk1.8的Stream流介绍和使用,流式操作

15 篇文章 0 订阅
本文介绍了Java 1.8中的Stream API,包括其基本概念、创建Stream的四种方式、筛选、映射、排序、查询操作、累积及Collectors的使用,通过实例展示了Stream如何进行数据处理和转换,帮助理解Stream的懒加载和计算特性。
摘要由CSDN通过智能技术生成

1. 简介

流是一种数据渠道,用于操作数据源(集合、数组)所声称的元素系列
集合讲的是数据,流讲的是计算。
注意:

  1. Stream是不会存储元素
  2. Stream不会改变源对象,他们会返回一个持有新结果都是Stream
  3. Stream操作是延使操作
  4. Stream流的操作,都是懒加载,只有终止操作时才会执行。

1.1. 基本使用

public class User{
	private Long id;
	private String name;
	private Integer age;
}

List<User> list = Arrays.asList(
        new User("段誉","男",18),
        new User("段誉","男",18),
        new User("段誉","男",14),
        new User("段誉","男",27),
        new User("段誉","男",null),
        new User("段誉","男",36)
);
// 拿到 list 中的所有 id 并转换成 list<Long>
List<Long> userIds = list.stream().map(User::getId).collect(Collectors.toList());

// 拿到 list 中的所有id并转换成 list<String>
List<String> userIds = list.stream()
							.map(User::getId)
							.map(String::valueOf)
							.collect(Collectors.toList());

2. 创建Stream的四种方式

 		// 第一种:Collection 的 stream 或者 parallelStream 方法创建
        List<String> list = new ArrayList<>();
        Stream<String> s1 = list.stream();

        // 第二种:通过Arrays的静态方法 stream 创建
        User[] users = new User[10];
        Stream<User> s2 = Arrays.stream(users);

        // 第三种:通过Stream的静态方法 of()
        Stream<String> s3 = Stream.of("我","长", "的", "像","吴", "彦", "祖");

        // 第四种:创建无限流
        // 迭代
        Stream<Integer> s4 = Stream.iterate(0, x -> x + 2);
        s4.forEach(System.out::println);

        // 生成
        Stream.generate(() -> Math.random()).forEach(System.out::println);

3. 筛选

filter:接收Lambda表达式,从流中排除数据。
limit:返回前n条数据。
skip:跳过前n条数据,若流中不足n条元素,则返回空流。
distinct:去重,但是对象必须重写equals和hashCode方法。

List<User> list = Arrays.asList(
        new User("段誉","男",18),
        new User("段誉","男",18),
        new User("段誉","男",14),
        new User("段誉","男",27),
        new User("段誉","男",null),
        new User("段誉","男",36)
);

// 年龄大于18岁
list.stream().filter(e -> e.getAge() > 18).forEach(System.out::println);

// 取前两条数据
list.stream().filter(e -> e.getAge() > 18).limit(2).forEach(System.out::println);

// 跳过前一条数据
list.stream().filter(e -> e.getAge() > 18).skip(1).forEach(System.out::println);

// 去重
list.stream().distinct().forEach(System.out::println);

// 注意点:如果查询的获取list中的所有年龄时,返回结果还是6个,一般情况下建议做过滤处理
list.stream()
	.map(User::getAge)
	.filter(ObjectUtil::isNotEmpty) // 将为空的数据过滤掉
	.forEach(System.out::println);

4. 映射

map:接收Lambda,将元素转换或提取信息,每一个元素都会被应用,并返回一个新的元素。
flatMap:接收一个函数作为参数,将流中的每个值都转换成另一个流,然后把所有流连成一个流
注:区别可以参考list集合的add方法和addAll方法

List<User> list = Arrays.asList(
        new User("段誉","男",18),
        new User("段誉","男",18),
        new User("段誉","男",14),
        new User("段誉","男",27),
        new User("段誉","男",36)
);

@Test
public void test3(){
    list.stream().map(e -> e.getAge()).forEach(System.out::println);

    List<String> str = Arrays.asList("aaa","bbb","ccc");
    str.stream().map(e -> toCharArr(e)).forEach(e -> e.forEach(System.out::println));

    str.stream().flatMap(e -> toCharArr(e)).forEach(System.out::println);


}

public static Stream<Character> toCharArr(String str){
    List<Character> arr = new ArrayList<>();
    for (Character c : str.toCharArray()) {
        arr.add(c);
    }
    return arr.stream();
}

5. 排序

sorted:无参,表示自然排序(按照abc这样排序),默认有序
可以在其中追加reversed使其倒序
有参,自定义排序

List<User> list = Arrays.asList(
        new User("段誉","男",18),
        new User("段誉","男",18),
        new User("段誉","男",14),
        new User("段誉","男",27),
        new User("段誉","男",36)
);

@Test
public void test4(){
    List<String> str = Arrays.asList("aaa","ddd","bbb","ccc");
    str.stream().sorted().forEach(System.out::println);

    // 根据年龄排序,如果年龄相同,那么根据姓名排序
    list.stream().sorted((x,y) -> {
        if(x.getAge().equals(y.getAge())){
            return x.getName().compareTo(y.getName());
        }else{
            return x.getAge().compareTo(y.getAge());

        }
    }).forEach(System.out::println);
}

// 根据年龄倒序排序
@Test
public void test4(){
    List<String> str = Arrays.asList("aaa","ddd","bbb","ccc");
    str.stream().sorted().forEach(System.out::println);

    list.stream().sorted(
        Comparator.comparing(User::getAge).reversed()
    ).forEach(System.out::println);
}

6. 查询操作

allMatch:是否所有数据都满足该条件
anyMatch:所有数据中是否有一个元素满足该条件
noneMatch:检查是否没有匹配所有元素
findFirst:返回第一个元素
findAny:返回当前流中任意元素
count:返回当前流中的元素的总数
max:返回流中的最大值
min:返回流中的最小值

List<User> list = Arrays.asList(
        new User("段誉","男",18),
        new User("段誉","男",18),
        new User("段誉","男",14),
        new User("段誉","男",27),
        new User("段誉","男",36)
);

@Test
public void test5(){
    // 是否所有数据都满足该条件
    boolean b = list.stream().allMatch(e -> e.getAge() > 28);
    System.out.println(b);

    // 所有数据中是否有一个元素满足该条件
    boolean b1 = list.stream().anyMatch(e -> e.getAge() > 28);
    System.out.println(b1);

    // 检查是否没有匹配所有元素
    boolean b2 = list.stream().noneMatch(e -> e.getAge() > 28);
    System.out.println(b2);

    // 返回第一个元素
    Optional<User> first = list.stream().findFirst();
    System.out.println(first);

    // 返回当前流中任意元素
    Optional<User> any = list.stream().findAny();
    System.out.println(any);

    // 返回当前流中的元素的总数
    long count = list.stream().count();
    System.out.println(count);


    // 返回流中的最大值
    Optional<User> max = list.stream().max((x,y) -> Integer.compare(x.getAge(),y.getAge()));
    System.out.println(max);

    Optional<Integer> min = list.stream().map(User::getAge).min(Integer::compare);
    System.out.println(min);
}

7. 累积

reduce:将流中的数据反复结合起来,得到一个值
collect:收集,将流转换成其他形式,接收Collector接口实现,用于汇总

 // 总年龄
        // 注:0会赋值给x,每次循环的元素都是y
        Integer reduce = list.stream().map(User::getAge).reduce(0, (x, y) -> x + y);
        System.out.println(reduce);
        // 同上
        Optional<Integer> reduce1 = list.stream().map(User::getAge).reduce(Integer::sum);
        System.out.println(reduce1);

        // 取出集合中的年龄,并转换成list集合
        List<Integer> collect = list.stream().map(User::getAge).collect(Collectors.toList());
        System.out.println(collect);

        // 取出集合中的年龄,并转换成hashSet集合
        HashSet<Integer> collect1 = list.stream().map(User::getAge).collect(Collectors.toCollection(HashSet::new));
        System.out.println(collect1);

        // 取出集合中年龄最大的元素,同理,还有:平均值、总数、最小值等多个方法
        Optional<User> max = list.stream().max((x, y) -> Integer.compare(x.getAge(), y.getAge()));
        System.out.println(max.get());

8. Collectors

toList:转换成list集合
toCollection(集合):转换成集合
groupingBy(流的值):按照给定的值分组
joining:拼接
summarizingInt(值):返回结果集

 // 取出集合中的年龄,并转换成hashSet集合
    HashSet<Integer> collect1 = list.stream().map(User::getAge).collect(Collectors.toCollection(HashSet::new));
    System.out.println(collect1);

    // 取出集合中年龄最大的元素,同理,还有:平均值、总数、最小值等多个方法
    Optional<User> max = list.stream().max((x, y) -> Integer.compare(x.getAge(), y.getAge()));
    System.out.println(max.get());

    // 等同于同上
    IntSummaryStatistics collect2 = list.stream().collect(Collectors.summarizingInt(User::getAge));
    System.out.println(collect2.getMax());
    System.out.println(collect2.getMin());
    System.out.println(collect2.getAverage());

    // 根据性别分组
    Map<String, List<User>> collect3 = list.stream().collect(Collectors.groupingBy(User::getSex));
    System.out.println(collect3);

    // 根据性别分组后再根据姓名分组
    Map<String, Map<String, List<User>>> collect4 = list.stream().collect(Collectors.groupingBy(User::getSex,Collectors.groupingBy(User::getName)));
    System.out.println(collect4);

    // 连接元素的所有姓名
    String collect5 = list.stream().map(User::getName).collect(Collectors.joining());
    System.out.println(collect5);
    // 以逗号隔开
    String collect6 = list.stream().map(User::getName).collect(Collectors.joining(","));
    System.out.println(collect6);
    // 前后都加== 并以逗号隔开
    String collect7 = list.stream().map(User::getName).collect(Collectors.joining(",","==","=="));
    System.out.println(collect7);

我真的有点像

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值