关于JAVA8的 Stream学习

目录
  • 一、Stream的使用
    • 1.1 创建
    • 1.2 步骤
    • 二、Stream的特性
    • 三、中间操作
      • 3.1 filter()
      • 3.2 limit()
      • 3.3 skip()
      • 3.4 map()
      • 3.5 sorted
    • 四、终止操作
      • 4.1 allMatch
      • 4.2anyMatch
      • 4.3noneMatch
      • 4.4 findFirst()
      • 4.5 findAny()
      • 4.6 count
      • 4.7 max
      • 4.8 min
      • 4.9 forEach
      • 4.10 reduce
      • 4.11 collect

一、Stream的使用

1.1 创建

  • 通过Collection接口的实现类提供的 stream()方法,或
  • 通过Arrays中的静态方法 stream()获取
  • 通过Stream类中的静态方法 of()
  • 无限流(迭代/生成)
/**
 * @Author: 郜宇博
 * @Date: 2021/9/1 23:28
 * 流操作
 */
public class StreamTests {
    @Test
    public void test(){
        //1.通过Collection接口的实现类提供的 stream()方法,或
        Collection<String> list = new ArrayList<>();
        list.stream();
        list.parallelStream();
        //2.通过Arrays中的静态方法 stream()获取
        Integer[] integers = new Integer[10];
        Arrays.stream(integers);
        //3.通过Stream类中的静态方法 of()
        Stream<String> stream = Stream.of("1","2");
        //4.无限流
        //迭代
        Stream<Integer> iterate = Stream.iterate(0, (x) -> x + 2);
        //生成
        Stream<Double> generate = Stream.generate(() -> Math.random());
    }
}
1.1.1并行流parallelStream

parallelStream提供了流的并行处理,它是Stream的另一重要特性,其底层使用Fork/Join框架实现。简单理解就是多线程异步任务的一种实现。

1.2 步骤

  • 创建Stream;
  • 转换Stream,每次转换原有Stream对象不改变,返回一个新的Stream对象(可以有多次转换);
  • 对Stream进行聚合(Reduce)操作,获取想要的结果;

二、Stream的特性

惰性求值:

多个中间操作可以连接起来形成一个流水线,除非流水线上触发终止操作,否则中间操作不会执行任何处理!而是在终止操作时一次性全部处理,这种情况称为“惰性求值”。

三、中间操作

筛选与切片

3.1 filter()

接受lambda表达式,从流中排除某些元素

@Test
public void test2(){
    //获取一个数组
    ArrayList<Integer> arrayList = new ArrayList<>();
    for (int i = 0; i <10; i++) {
        arrayList.add(i);
    }
    //流操作:获取大于5的
    arrayList.stream().filter((num)->num>5).forEach(System.out::println);
}
//结果:  6 7 8 9

3.2 limit()

截断流,使其元素个数不超过一定数量

满足limit的数量后,就短路,不在执行后续操作

@Test
public void test2(){
    //获取一个数组
    ArrayList<Integer> arrayList = new ArrayList<>();
    for (int i = 0; i <10; i++) {
        arrayList.add(i);
    }
    //流操作:获取大于5的
    arrayList.stream().filter((num)->num>5)
                    .limit(2)
                    .forEach(System.out::println);
}
//结果: 6 7

3.3 skip()

跳过元素,跳过前n个元素,执行后面的元素,如果不足n个则返回空流

@Test
public void test2(){
    //获取一个数组
    ArrayList<Integer> arrayList = new ArrayList<>();
    for (int i = 0; i <10; i++) {
        arrayList.add(i);
    }
    //流操作:获取大于5的
    arrayList.stream().filter((num)->num>5)
                    .skip(2)
                    .forEach(System.out::println);
}
//结果: 8 9
3.3 map()
映射,在方法中使用方法Function< T> 函数型接口 -----> R apply(T t);

@Test
public void  test4(){
    //获取一个list
    List<String> list = Arrays.asList("aaa","bbb","ccc");
    //使用流操作 转化大写
    list.stream().map((str)->str.toUpperCase())
            .forEach(System.out::println);
}
/*结果:AAA
  BBB
        CCC*/
@Test
public void test3(){
    //获取一个list
    List<String> list = Arrays.asList("aaa","bbb","ccc");
    //流操作: 将list中的元素取出
    //第一步使用map取出流,流里存放的还是流
    //因此需要二次foreach
    Stream<Stream<Character>> chs = list.stream().map(StreamTests::getUpper);
            chs.forEach((stream)->{
                stream.forEach(System.out::print);
            });
}
//将str返回为流对象
public static Stream<Character> getUpper(String str){
    List<Character> list = new ArrayList<>();
    for (Character character: str.toCharArray()){
        list.add(character);
    }
    return list.stream();
}
//结果:aaabbbccc

3.4 map()

映射,在方法中使用方法Function< T> 函数型接口 -----> R apply(T t);

@Test
public void  test4(){
    //获取一个list
    List<String> list = Arrays.asList("aaa","bbb","ccc");
    //使用流操作 转化大写
    list.stream().map((str)->str.toUpperCase())
            .forEach(System.out::println);
}
/*结果:AAA
  BBB
        CCC*/
@Test
public void test3(){
    //获取一个list
    List<String> list = Arrays.asList("aaa","bbb","ccc");
    //流操作: 将list中的元素取出
    //第一步使用map取出流,流里存放的还是流
    //因此需要二次foreach
    Stream<Stream<Character>> chs = list.stream().map(StreamTests::getUpper);
            chs.forEach((stream)->{
                stream.forEach(System.out::print);
            });
}
//将str返回为流对象
public static Stream<Character> getUpper(String str){
    List<Character> list = new ArrayList<>();
    for (Character character: str.toCharArray()){
        list.add(character);
    }
    return list.stream();
}
//结果:aaabbbccc
3.3.1 flatMap

相当于集合方法的 addAll

即:将流中的流内元素取出,放入一个流中,而不是流内套流

@Test
public void test3(){
    //获取一个list
    List<String> list = Arrays.asList("aaa","bbb","ccc");
    //流操作: 将list中的元素取出
    //第一步使用map取出流,流里存放的还是流
    //因此需要二次foreach
    Stream<Stream<Character>> chs = list.stream().map(StreamTests::getUpper);
            chs.forEach((stream)-> stream.forEach(System.out::print));

    System.out.println("\n=====");
    //方法二:
    //使用flatMap
    list.stream().flatMap(StreamTests::getUpper).forEach(System.out::print);
}

3.5 sorted

@Test
public void test5(){
    List<String> list = Arrays.asList("aaa", "ccc", "bbbb", "eeeee");
    //自然排序
    list.stream()
            .sorted()
            .forEach(System.out::println);
    System.out.println("=============");
    //定制排序
    list.stream()
            .sorted((x,y)->{
                //如果长度一样,则按照字典排序
                if (x.length() == y.length()){
                    return x.compareTo(y);
                }
                //如果长度不一样则按照长度的降序排序
                else {
                    return y.length() - x.length();
                }
            })
            .forEach(System.out::println);

}
/*结果:
aaa
bbbb
ccc
eeeee
=============
eeeee
bbbb
aaa
ccc
*/

四、终止操作

查找与匹配

4.1 allMatch

Predicate<? super T> predicate
/**
 * @Author: 郜宇博
 * @Date: 2021/9/3 14:00
 * 终止操作
 */
public class FinalOperation {
    static ArrayList<Student> list;
    /**
     * allMath 检查是否全部元素符合
     */
    @BeforeEach
    public void before(){
        //准备集合
        Student student1 = new Student(10,"张三", Student.Status.Sad);
        Student student2 = new Student(20,"李四", Student.Status.Happy);
        Student student3 = new Student(30,"王五", Student.Status.Free);
        Student student4 = new Student(18,"田七", Student.Status.Free);
        Student student5 = new Student(140,"赵六", Student.Status.Tired);
        list = new ArrayList<>();
        list.add(student1);
        list.add(student2);
        list.add(student3);
        list.add(student4);
        list.add(student5);
    }
}
class Student{
    private int age;
    private String name;
    private Status status;

    public int getAge() {
        return age;
    }

    public String getName() {
        return name;
    }

    public Status getStatus() {
        return status;
    }

    /**
     * 枚举状态
     */
    public enum Status{
        Free,Tired,Happy,Sad;
    }

    public Student(int age, String name, Status status) {
        this.age = age;
        this.name = name;
        this.status = status;
    }
}
/**
     * 是否全部年龄都大于20
     */
    @Test
    public void test1(){
        boolean b = list.stream().allMatch((s) -> s.getAge() > 20);
        System.out.println(b);
    }
//结果: false

4.2anyMatch

Predicate<? super T> predicate
/**
 * 是否存在年龄大于20的
 */
@Test
public void test2(){
    boolean b = list.stream().anyMatch((s) -> s.getAge() > 20);
    System.out.println(b);
}
//结果:true

4.3noneMatch

Predicate<? super T> predicate
/**
 * 是否没有满足年龄大于20的
 *
 */
@Test
public void test3(){
    boolean b = list.stream().noneMatch((s) -> s.getAge() > 20);
    System.out.println(b);
}
//结果:false

4.4 findFirst()

返回第一元素,但结果可能为null, 因此使用Optional<T> 来接收,如果为null则可以替换。

/**
 * 返回第一元素
 */
@Test
public void test4(){
    Optional<Student> first = list.stream()
            .filter((e) -> e.getStatus().equals(Student.Status.Free))
            .findFirst();
    System.out.println(first);
}
//结果:Optional[Student{age=30, name='王五', status=Free}]

4.5 findAny()

返回任意一个

/**
 * 返回任意一个
 *
 */
@Test
public void test5(){
    Optional<Student> b = list.parallelStream()
            .filter((student -> student.getAge()<30))
            .findAny();
     System.out.println(b.get());
}
//结果: 任意一个年龄小于30的学生

4.6 count

/**
 * 获取数量count
 */
@Test
public void test6(){
    long count = list.stream().count();
    System.out.println(count);
}
//结果 : 5

4.7 max

/**
     * 获得最大值
     */
    @Test
    public void test7(){
        Optional<Integer> max = list.stream()
                .map(x->x.getAge())
                .max(Integer::compare);
        System.out.println(max.get());

    }
//结果: 140

4.8 min

/**
 * 获得最小值
 */
@Test
public void test7(){
    Optional<Integer> max = list.stream()
            .map(x->x.getAge())
            .min(Integer::compare);
    System.out.println(max.get());
}

4.9 forEach

@Test
public void test2(){
    //获取一个数组
    ArrayList<Integer> arrayList = new ArrayList<>();
    for (int i = 0; i <10; i++) {
        arrayList.add(i);
    }
    //流操作:获取大于5的
    arrayList.stream().filter((num)->num>5)
                    .limit(2)
                    .forEach(System.out::println);
}
//结果: 6 7

4.10 reduce

/**
     * 归纳
     */
    @Test
    public void test8(){
        Integer reduce = list.stream()
                .map(Student::getAge)
                .reduce(0, (x, y) -> x + y);
        System.out.println(reduce);
        //方法二:
        //此方法有可能为null,因此封装为Optional对象
        Optional<Integer> reduce1 = list.stream()
                .map(Student::getAge)
                .reduce(Integer::sum);
        System.out.println(reduce1.get());
    }

4.11 collect

可以收集为集合类,

可以在收集后进行分组、多级分组、分片

/**
 * 收集
 */
@Test
public void test9(){
    List<Student> collect = list.stream().collect(Collectors.toList());
    collect.forEach(System.out::println);
    //方式二:
    HashSet<Student> collect1 = list.stream().collect(Collectors.toCollection(HashSet::new));
    collect.forEach(System.out::println);
}
/*
结果:Student{age=10, name='张三', status=Sad}
Student{age=20, name='李四', status=Happy}
Student{age=30, name='王五', status=Free}
Student{age=18, name='田七', status=Free}
Student{age=140, name='赵六', status=Tired}
*/
/**
 * 使用收集可以计算最大值、最小值、平均值、等
 * 也可以进行分组
 */
@Test
public void test10(){
    Map<Student.Status, List<Student>> collect = list.stream().collect(Collectors.groupingBy((x) -> x.getStatus()));
    System.out.println(collect.size());
    System.out.println(collect);
}

到此这篇关于JAVA8 Stream学习的文章就介绍到这了,更多相关JAVA8 Stream内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java8的Stream()与ParallelStream()的区别说明

    Java8 Stream()与ParallelStream()区别 Stream 无状态:指元素的处理不受之前元素的影响: 有状态:指该操作只有拿到所有元素之后才能继续下去. 非短路操作:指必须处理所有元素才能得到最终结果: 短路操作:指遇到某些符合条件的元素就可以得到最终结果,如 A || B,只要A为true,则无需判断B的结果. ParallelStream 对于ParallelStream,需要知道的是里面的执行是异步的,并且使用的线程池是ForkJoinPool.common,可以通过

  • 一篇文章带你了解Java Stream流

    目录 一.Stream流引入 现有一个需求: 1.用常规方法解决需求 2.用Stream流操作集合,获取流,过滤操作,打印输出 二.Stream流的格式 三.获取流 四.Stream流的常用方法 方法演示: 1.count方法: 2.filter方法: 3.forEach方法 4.limit方法 5.map方法 6.skip方法 7.concat方法 五.收集Stream流 总结 一.Stream流引入 Lambda表达式,基于Lambda所带来的函数式编程,又引入了一个全新的Stream概念,

  • Java8 中使用Stream 让List 转 Map使用问题小结

    在使用 Java 的新特性 Collectors.toMap() 将 List 转换为 Map 时存在一些不容易发现的问题,这里总结一下备查. 空指针风险 java.lang.NullPointerException 当 List 中有 null 值的时候,使用 Collectors.toMap() 转为 Map 时,会报 java.lang.NullPointerException,如下: List<SdsTest> sdsTests = new ArrayList<>(); S

  • java8 Stream list to Map key 重复 value合并到Collectio的操作

    java8 Stream list to Map key 重复 value合并到Collectio 关于把list转换成key value的map有很多博客上都有实现,这里是一个把value放入到集合中去 List<String> list = Lists.newArrayList("1", "2", "3", "1"); Map<String, List<String>> map = li

  • 总结一下关于在Java8中使用stream流踩过的一些坑

    Java8的stream流 第一个坑: Collectors.toAsList()其实是new了一个list,在向里面赋值. 注意这里Collectors.toList()的写法,这里其实是底层new ArraryList().筛选的数据放到一个新的list.虽然标1处和标2处是同一个变量,但是内存地址是不一样啊.下面的逻辑时把hldrPolVOList中的某些元素删除.但是这个方法执行完后其实是没有删除里面元素的.原因就是这里的new ArraryList()更改了内存地址造成的. 测试: 解

  • 解析Java8 Stream原理

    目录 一.前言 二.Stream流水线解决方案 2.1.操作如何记录 2.2.操作如何叠加 2.3.叠加之后的操作如何执行 一.前言 首先我们先看一个使用Stream API的示例,具体代码如下: 这是个很简单的一个Stream使用例子,我们过滤掉空字符串后,转成int类型并计算出最大值,这其中包括了三个操作:filter.mapToInt.sum.相信大多数人再刚使用Stream API的时候都会有个疑问,Stream是指怎么实现的,是每一次函数调用就执行一次迭代吗?答案肯定是否,因为如果真的

  • Java FileInputStream与FileOutputStream使用详解

    什么是InputStream和OutputStream? InputStream和OutputStream是抽象类,是所有字节输入流和输出流的父类.这里,我们首先要分清楚两个概念: InputStream(输入流):输入流是用来读入数据的.- - - > > >读入 OutputStream(输出流):输出流是用来写出数据的.- - - > > >写出 文件输入流--FileInputStream FileInputStream 从文件系统中的某个文件中获得输入字节.

  • Java inputstream和outputstream使用详解

    计算机在进行I/O时都是以流的形式来进行,Java中所有流的相关操作的类,都继承自以下四个抽象类. 输入流 输出流 字节流 InputStream OutputStream 字符流 Reader Writer InPutStream的实现 import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java

  • java8 使用stream排序空字段排在前面或后面

    java8 stream排序空字段排在前面或后面 直接粗暴sorted会NPE,这种写法可以避免 list.stream().sorted(Comparator.comparing(l -> l.getCreateTime(), Comparator.nullsFirst(Date::compareTo))).collect(toList()); toOrderList.stream().sorted(Comparator.comparing(l -> l.getContractCode(),

  • Java之OutputStreamWriter流案例详解

    一.OutputStreamWriter流     API说明:OutputStreamWriter是从字符流到字节流的桥接:使用指定的字符集将写入其中的字符编码为字节.它使用的字符集可以通过名称指定,也可以明确指定,或者可以接受平台的默认字符集. 每次调用write()方法都会导致在给定字符上调用编码转换器.生成的字节在写入底层输出流之前在缓冲区中累积.可以指定此缓冲区的大小,但默认情况下,它足够大,可用于大多数用途.请注意,传递给write()方法的字符不会被缓冲. 为了获得最高效率,请考虑

  • JAVA 笔记 ClassLoader.getResourceAsStream() 与 Class.getResourceAsStream()的区别

    Class.getResourceAsStream() 会指定要加载的资源路径与当前类所在包的路径一致. 例如你写了一个MyTest类在包com.test.mycode 下,那么MyTest.class.getResourceAsStream("name") 会在com.test.mycode包下查找相应的资源. 如果这个name是以 '/' 开头的,那么就会从classpath的根路径下开始查找. ClassLoader.getResourceAsStream() 无论要查找的资源前

  • 基于Java8并行流(parallelStream)的注意点

    Java8并行流(parallelStream)注意点 在最初使用并行流的时候,查询列表会偶尔性报空指针异常,这令我非常纳闷 代码是这样的: List<OrderListVO> orderListVOS = new LinkedList<OrderListVO>(); baseOrderBillList.parallelStream().forEach(baseOrderBill -> { OrderListVO orderListVO = new OrderListVO()

  • 手把手带你了解Java-Stream流方法学习及总结

    目录 前言 forEach() map() map()源码: filter() filter()源码: sorted() sorted()源码: collect() collect()源码: 总结 前言 Stream是一个来自数据源的元素队列并支持聚合操作,其中具有以下特性: Stream只负责计算,不存储任何元素,元素是特定类型的对象,形成一个队列 数据源可以实集合.数组.I/O channel.generator等 聚合操作有类似SQL的:filter.map.match.sorted等操作

  • 如何用Java Stream写出既高雅又装*的代码

    目录 一. 冷静分析 二. 直接开装 2.1 初级炫 2.2 普通炫 2.3 高级炫 2.4 再炫一波 拿到当前key与对应的数量 2.5 Map Reduce炫 git仓库直达 List<String> strings = Lists.newArrayList("name=kk", "sex=1", "tel=1111", "email=xx@qq.com","name=ww","n

随机推荐