Java 关于jdk1.8的Stream流的一些使用总结

Java 关于jdk1.8的Stream流的一些使用总结

最近看了一些关于jdk1.8新出的stream流的一些使用方式,发现很多东西在开发中能节省不少的代码量,并且十分方便,所以在这里做一些总结。

1 . 使用场景

下面都是自己的一些理解,如果有错误,请多指教;
stream流主要对集合进行操作,在真正的项目中有许多操作结合这样的场景,比如说我们从数据库查询出来的数据,需要做一层过滤,再比如所,我们要在结果集里对数据进行操作等,这写都需要我们做循环,再筛选,再进行操作,其实这并不难,但这些都给我们增加了大量的代码量,如果用stream流,用一行代码就可以解决我们的需求!

2 . 如何获取stream流对象

在jdk1.8以后,我们会发现 Collection里新增加了一个接口 Collection default Stream stream(),这说明我们的集合对象中会新增加一个方法,我们调用这个方法试试,就可以获取到我们需要的stream流对象,而我们对集合进行的操作,也都是通过这个stream流对象进行操作的。
代码对应如下:
示例代码:

public static void main(String[] args){

        List<String> strList = new ArrayList<>();
        strList.add("shaochen");
        strList.add("shaohen");
        strList.add("cool");
        strList.add("bean");
        strList.add("java");
        strList.add("java");

        // 这行获取我们的stream流对象,我们的操作都是通过这个流对象进行操作的。
        Stream<String> stream = strList.stream();

        // 首先我们做一个简单的循环遍历
        stream.forEach(System.out::println);

    }
3 . 使用stream流获取集合的长度

示例代码:

public static void main(String[] args){

        List<String> strList = new ArrayList<>();
        strList.add("shaochen");
        strList.add("shaohen");
        strList.add("cool");
        strList.add("bean");
        strList.add("java");
        strList.add("java");

        // 这行获取我们的stream流对象,我们的操作都是通过这个流对象进行操作的。
        Stream<String> stream = strList.stream();

        long count = stream.count();
        System.out.println(count);

    }
4 . 使用stream流对数据进行去重

示例代码:

    public static void main(String[] args){

        List<String> strList = new ArrayList<>();
        strList.add("shaochen");
        strList.add("shaohen");
        strList.add("cool");
        strList.add("bean");
        strList.add("java");
        strList.add("java");

        // 这行获取我们的stream流对象,我们的操作都是通过这个流对象进行操作的。
        Stream<String> stream = strList.stream();
         // 对数据进行去重并循环遍历结果
        stream.distinct().forEach(System.out::println);
    }

5 . 将stream流处理后的数据收集成一个集合

示例代码:

    public static void main(String[] args){

        List<String> strList = new ArrayList<>();
        strList.add("shaochen");
        strList.add("shaohen");
        strList.add("cool");
        strList.add("bean");
        strList.add("java");
        strList.add("java");

        // 这行获取我们的stream流对象,我们的操作都是通过这个流对象进行操作的。
        Stream<String> stream = strList.stream();
        // 去重后收集成一个集合
        List<String> collect = stream.distinct().collect(Collectors.toList());
        System.out.println(collect.toString());
    }
6 . stream流的循环

stream流里面有两个循环遍历的方式:

Stream<T> peek(Consumer<? super T> action); 
void forEach(Consumer<? super T> action);

既然出现了两种循环,肯定有一定的区别,如果你真的使用的话,你肯定会发现forEach使用后,我如果想再对stream流进行操作是不可行的,这是因为forEach是一种消费性接口,也就是返回值是void,也就是没有返回值的接口,而我们看其他的stream流提供的接口,大部分都是有返回值的,返回的也是一个Stream流对象。
前面第一个示例就是循环的示例,在这就不再重复写了

7 . stream流的map的使用

示例代码:

    public static void main(String[] args){

        List<String> strList = new ArrayList<>();
        strList.add("shaochen");
        strList.add("shaoChen");
        strList.add("cool");
        strList.add("bean");
        strList.add("java");
        strList.add("java");

        // 这行获取我们的stream流对象,我们的操作都是通过这个流对象进行操作的。
        Stream<String> stream = strList.stream();
        // 将集合中的数据循环变为大写字母,然后过滤,找到包含A的数据,循环打印出来
        stream.map(s -> s.toUpperCase()).filter(s -> s.contains("A")).forEach(System.out::println);
    }

map可以对stream流中的一行数据进行操作

8. stream流中的分页操作

示例代码:

 public static void main(String[] args){

        List<String> strList = new ArrayList<>();
        strList.add("shaochen");
        strList.add("shaoChen");
        strList.add("cool");
        strList.add("bean");
        strList.add("java");
        strList.add("java");
        // 这行获取我们的stream流对象,我们的操作都是通过这个流对象进行操作的。
        Stream<String> stream = strList.stream();
        // stream流对数据进行分页查询
        stream.skip(2).limit(2).forEach(s -> System.out.println(s));
    }

可以看到有两个方法,一个skip和一个limit,skip代表着要跳过结果集中的前几个数据,limit也就是取结果集中的几个数据,也就是一个是page字段,一个是size字段,可以做到简单的分页。

9. stream流中匹配条件

stream流中有两个匹配的接口,anyMatch和allMatch;
anyMatch: 只要有一条数据可以匹配,那就会返回true
allMatch: 必须要每一条数据都匹配才会返回true
由于用法都是一样的,这里就只用anyMatch作为示例
#####8.1 如果集合中匹配一条数据就返回true
当集合中一条数据包含字符"a",就返回true

    public static void main(String[] args){

        List<String> strList = new ArrayList<>();
        strList.add("shaochen");
        strList.add("shaoChen");
        strList.add("cool");
        strList.add("bean");
        strList.add("java");
        strList.add("java");
        // 这行获取我们的stream流对象,我们的操作都是通过这个流对象进行操作的。
        Stream<String> stream = strList.stream();
        
        if (stream.anyMatch(s -> s.contains("a"))) {
            System.out.println("匹配");
        }
    }

当然我们肯定会遇到多匹配条件的情况,这样就不做不到了?不存在的,往下看
#####8.2 如果集合中匹配多条数据就返回true
我们要先定义两个断言,也就是两个条件,然后我们在stream流里面有and或者or来进行判断,顾名思义,and就是两个条件在一行数据中全都匹配,在下面的代码中的含义就是:是否有一条数据中既有"a"又有"b",如果存在就返回true,or的含义就是有"a"或者"b"就可以匹配

    public static void main(String[] args){

        List<String> strList = new ArrayList<>();
        strList.add("shaochen");
        strList.add("shaoChen");
        strList.add("cool");
        strList.add("bean");
        strList.add("java");
        strList.add("java");
        // 这行获取我们的stream流对象,我们的操作都是通过这个流对象进行操作的。
        Stream<String> stream = strList.stream();

        Predicate<String> predicateOne = s -> s.contains("a");
        Predicate<String> predicateTwo = s -> s.contains("b");

        if (stream.anyMatch(predicateOne.and(predicateTwo))){
            System.out.println("匹配");
        }
    }

暂时也就能理解到这个层次,日后会有更新的,下期再见

10 补充:使用stream流对集合进行分组

这个功能,相当于将一个excel表格中的各个单元格进行合并,首先创建一个类,这里用于集合存放的数据类型,我相信这种场景我们会经常遇到的

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Demo {
    private String name;
    private Integer key;
}

接下来我们创建一个数据类型为Demo的集合,并放置一些默认的数据类型

	public static void main(String[] args){
        List<Demo> demos = new ArrayList<>();
        demos.add(getDemo("DaMing", 1));
        demos.add(getDemo("DaMing", 2));
        demos.add(getDemo("Amy", 3));
        demos.add(getDemo("Sam", 4));
        demos.add(getDemo("Sam", 5));
    }
    
    public static Demo getDemo(String name, Integer key) {
        return new Demo(name, key);
    }

现在这个集合里的数据如果对应在excel表格里的话,应该是这样的:
在这里插入图片描述
但是有时候,我们需要的并不应该是这样的数据结构,而是将他们都分好组,比如下图:在这里插入图片描述
对应我们的steam流就应该是如下的操作:

    public static void main(String[] args){
        List<Demo> demos = new ArrayList<>();
        demos.add(getDemo("DaMing", 1));
        demos.add(getDemo("DaMing", 2));
        demos.add(getDemo("Amy", 3));
        demos.add(getDemo("Sam", 4));
        demos.add(getDemo("Sam", 5));

        Map<String, List<Integer>> collect = demos.stream().collect(Collectors.groupingBy(Demo::getName, Collectors.mapping(Demo::getKey, Collectors.toList())));
        Set<String> keys = collect.keySet();
        keys.stream().forEach(s -> System.out.println(s + " --> " + collect.get(s).toString()));

    }

    public static Demo getDemo(String name, Integer key) {
        return new Demo(name, key);
    }

输出结果如下:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值