JAVA8 Stream学习

JAVA8 Stream学习

一、Stream的使用

1.1 创建

  1. 通过Collection接口的实现类提供的 stream()方法,或
  2. 通过Arrays中的静态方法 stream()获取
  3. 通过Stream类中的静态方法 of()
  4. 无限流(迭代/生成)
/**
 * @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.2并行流parallelStream

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

1.2 步骤

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

<span>JAVA8 Stream学习</span>

二、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.2 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.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.4 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);
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/115170.html原文链接:https://javaforall.net

(0)
上一篇 2021年11月12日 下午3:00
下一篇 2021年11月12日 下午4:00


相关推荐

  • 贝云cms内容管理系统(thinkphp5.0开源cms管理系统)

    贝云cms内容管理系统(thinkphp5.0开源cms管理系统)

    2021年11月6日
    76
  • mysql 家谱树查询_GitHub – chenwei/FamilyTreeView: 家谱树绘制Demo

    mysql 家谱树查询_GitHub – chenwei/FamilyTreeView: 家谱树绘制DemoFamilyTreeVi 重大改进 增加仿 亲友 App 的家谱 与之前的没有任何关联 可以直接翻到第二部分 仿亲友 家谱 部分进行阅读家谱树绘制 Demo 主要使用自定义 ViewGroup 和使用 canvas 进行划线 现阶段实现了自己 配偶 兄弟姐妹 父母 祖父母 外祖父母 子女和儿媳妇 女婿以及孙子 共五代的绘制 加入了 touch 事件可以移动 代码可能写得相对比较死 基本只能使用于家谱展示 还

    2026年3月16日
    1
  • pycharm 打不开了_pycharm激活成功教程之后打不开

    pycharm 打不开了_pycharm激活成功教程之后打不开pycharm打不开问题总结1:第一步:进入如下路径,找到cmd.exe,右键选择“以管理员身份运行”;第二步:在打开的cmd窗口中,输入netshwinsockreset,按回车键;第三步:重启电脑;第四步:重启后,双击pycharm图标就能打开了!2:你下载的应该是官方版的,然后自己加了网上下载的.jar激活成功教程插件,并添加了这个插件的路径到.vmoptions文件。打不开是因为你修改…

    2022年8月28日
    4
  • 费马小定理证明

    费马小定理证明费马小定理的证明如下 任意取一个质数 比如 13 考虑从 1 到 12 的一系列整数 1 2 3 4 5 6 7 8 9 10 11 12 给这些数都乘上一个与 13 互质的数 比如 3 得到 3 6 9 12 15 18 21 24 27 30 33 36 对于模 13 来说 这些数同余于 3 6 9 12 2 5 8 11 1 4 7 10 这些余数实际上就是原来的 1 2 3 4 5 6 7 8 9 10 11 1

    2026年3月18日
    2
  • vs2012密钥_ultimate2012产品密钥

    vs2012密钥_ultimate2012产品密钥MicrosoftVisualStudioUltimate2012旗舰版有效注册密钥:YKCW6-BPFPF-BT8C9-7DCTH-QXGWC;KCW6-BPFPF-BT8C9-7DCTH-QXGWC转载于:https://www.cnblogs.com/RogerLu/p/10070312.html

    2022年10月15日
    4
  • 如何在Ubuntu 14.04 和14.10 上安装新的字体

    如何在Ubuntu 14.04 和14.10 上安装新的字体

    2022年3月2日
    42

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号