Java8でストリームを使う方法

WBOY
リリース: 2023-05-30 14:22:11
転載
1407 人が閲覧しました

1. 経験豊富な退役軍人が Stream の使用を好む理由

  • 反復子と比較してパフォーマンス上の利点 (データ量が大きい)、高速です

  • シリアル処理と並列処理をサポートしており、並列処理はCPUリソースを最大限に活用できます

  • ストリームは計算データのストリームであり、データ自体は保存されません

  • 関数型プログラミングのサポート

  • コードは洗練されており、コードがより効率的で、クリーンで簡潔になります

2. Stream の使用方法

3 つのステップ:

  • 作成#Stream

  • 中間操作

  • #終了操作

  • #3. ストリームの作成

#Stream の作成

はデータ ソース (通常はコンテナーまたは配列) に依存します

Stream ストリームの作成は大きく 4 つのタイプに分けられ、最も一般的に使用されるのはコレクションを通じて作成することです

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class CreateStreamDemo {
    public static void main(String[] args) {
        // 1 通过集合创建Stream也是用的最多的一种形式
        List<String> strList = new ArrayList<>();
        strList.add("a");
        strList.add("b");
        strList.add("c");
        // 创建串行操作流
        Stream<String> stream = strList.stream();
        // 创建并行操作流
        Stream<String> parallelStream = strList.parallelStream();
        // 2 通过数组创建Stream
        int[] arr = new int[]{1,2,3};
        IntStream intStream = Arrays.stream(arr);
        // 3 通过Stream.of
        Stream<Integer> integerStream = Stream.of(1,2,3);
        Stream<String> stringStream = Stream.of("a","b","c");
        // 4 无限流
        // 每隔五个数取一个
        Stream.iterate(0, t -> t + 5).forEach(System.out::println); // 迭代
        Stream.generate(Math::random).forEach(System.out::println); // 生成
    }
}
ログイン後にコピー
4 . ストリームの中間操作

ストリーム

中間操作では、最も一般的に使用される操作は、フィルター処理、重複排除、並べ替えです。この章では、最も一般的に使用されるオブジェクトの重複排除とオブジェクトの更新について説明します。属性の組み合わせの並べ替え

import com.zhj.java8.bean.Student;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;
import java.util.stream.Stream;
import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.toCollection;

public class MiddleStreamDemo {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student(1,"小华",23,1));
        students.add(new Student(1,"小华",23,2));
        students.add(new Student(2,"小米",20,2));
        students.add(new Student(3,"小果",30,3));
        students.add(new Student(4,"小维",18,2));
        // 过滤
        students.stream().filter(stu -> stu.getAge() > 20).forEach(System.out::println);
        // 去重
        // 对对象去重是根据引用去重,内容重复并不会去重,除非重写equals和hashCode方法
        System.out.println("----------去重----------");
        System.out.println("去重1----------");
        students.stream().distinct().forEach(System.out::println);
        // 对集合中对象某些属性去重,不重写equals和hashCode方法,只能借助其他数据结构来辅助去重
        // 单个属性可以stu -> stu.getId()
        // 多个属性可以stu -> stu.getId() + ";" + stu.getName()
        System.out.println("去重2----------");
        ArrayList<Student> distinctList = students.stream().collect(
                collectingAndThen(toCollection(() -> new TreeSet<>(Comparator.comparing(stu -> stu.getId() + ";" + stu.getName()))), ArrayList::new)
        );
        distinctList.stream().forEach(System.out::println);
        // 排序 支持定义排序方式
        // sorted 默认使用 自然序排序, 其中的元素必须实现Comparable 接口
        System.out.println("----------排序----------");
        System.out.println("排序1----------");
        students.stream().sorted().forEach(System.out::println);
        // sorted(Comparator<? super T> comparator) :我们可以使用lambada 来创建一个Comparator 实例。可以按照升序或着降序来排序元素。
        System.out.println("排序2----------");
        students.stream()
                .sorted(Comparator.comparing(Student::getAge,Comparator.reverseOrder())) // ,Comparator.reverseOrder() 逆序
                .forEach(System.out::println);
        // 创建比较器,通过对比较器内容的定义实现对多个属性进行排序,类似sql中连续的orderBy
        System.out.println("排序3----------");
        students.stream().sorted(
                (s1,s2) -> {
                    if (s1.getAge() == s2.getAge()) {
                        return s1.getSex().compareTo(s2.getSex());
                    } else {
                        return -s1.getAge().compareTo(s2.getAge());
                    }
                }
        ).forEach(System.out::println);
        System.out.println("排序4----------");
        Comparator<Student> studentComparator = (s1,s2) -> {
            Integer age1 = s1.getAge();
            Integer age2 = s2.getAge();
            if (age1 != age2) return age1 - age2;
            Integer sex1 = s1.getSex();
            Integer sex2 = s2.getSex();
            if (sex1 != sex2) return sex2 - sex1;
            return 0;
        };
        students.stream().sorted(studentComparator).forEach(System.out::println);
        // 截取 截取前三个元素
        System.out.println("----------截取----------");
        students.stream().limit(3).forEach(System.out::println);
        // 跳过 跳过前3个元素
        System.out.println("----------跳过----------");
        students.stream().skip(3).forEach(System.out::println);
        // 映射
        System.out.println("----------映射----------");
        System.out.println("映射Map----------");
        // map接收Lambda,将元素转换其他形式,或者是提取信息,并将其映射成一个新的元素
        Stream<Stream<Student>> streamStream1 = students.stream().map(str -> filterStudent(str));
        streamStream1.forEach(sm -> sm.forEach(System.out::println));
        System.out.println("映射flatMap----------");
        // map接收Lambda,将流中的每一个元素转换成另一个流,然后把所有流连成一个流 扁平化映射
        Stream<Student> studentStream2 = students.stream().flatMap(str -> filterStudent(str));
        studentStream2.forEach(System.out::println);
        // 消费
        System.out.println("----------消费----------");
        students.stream().peek(stu -> stu.setAge(100)).forEach(System.out::println);
    }
    public static Stream<Student> filterStudent(Student student) {
        student = new Student();
        return Stream.of(student);
    }
}
ログイン後にコピー
Student

public class Student implements Comparable<Student> {
    private Integer id;
    private String name;
    private Integer age;
    private Integer sex;
    public Student() {
    }
    public Student(Integer id, String name, Integer age, Integer sex) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.sex = sex;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public Integer getSex() {
        return sex;
    }
    public void setSex(Integer sex) {
        this.sex = sex;
    }
    @Override
    public String toString() {
        return "Student{" +
                "id=&#39;" + id + &#39;\&#39;&#39; +
                ", name=&#39;" + name + &#39;\&#39;&#39; +
                ", age=&#39;" + age + &#39;\&#39;&#39; +
                ", sex=" + sex +
                &#39;}&#39;;
    }
    @Override
    public int compareTo(Student o) {
        return this.getAge() - o.getAge();
    }
}
ログイン後にコピー
5. ストリーム終了操作

ストリーム ## の終了操作#、最も一般的に使用される目的は、処理されたデータを新しいコンテナーに収集することであり、同時に SQL 集計関数

package com.zhj.java8.stream;
import com.zhj.java8.bean.Student;
import java.util.*;
import java.util.stream.Collectors;
public class TerminationStreamDemo {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student(1,"小华",23,1));
        students.add(new Student(2,"小米",20,2));
        students.add(new Student(3,"小果",30,3));
        students.add(new Student(4,"小维",18,2));
        students.add(new Student(5,"小华",23,2));
        System.out.println("--------------------匹配聚合操作--------------------");
        // allMatch:接收一个 Predicate 函数,当流中每个元素都符合该断言时才返回true,否则返回false
        boolean allMatch = students.stream().allMatch(stu -> stu.getAge() > 10);
        System.out.println("全部符合大于10岁条件:" + allMatch);
        // noneMatch:接收一个 Predicate 函数,当流中每个元素都不符合该断言时才返回true,否则返回false
        boolean noneMatch = students.stream().noneMatch(stu -> stu.getAge() > 10);
        System.out.println("全部不符合大于10岁条件:" + noneMatch);
        // anyMatch:接收一个 Predicate 函数,只要流中有一个元素满足该断言则返回true,否则返回false
        boolean anyMatch = students.stream().anyMatch(stu -> stu.getAge() > 20);
        System.out.println("含有任意符合大于20岁条件:" + anyMatch);
        // findFirst:返回流中第一个元素
        Student findFirst = students.stream().findFirst().get();
        System.out.println("第一个学生:" + findFirst);
        // findAny:返回流中的任意元素
        Student findAny = students.stream().findAny().get();
        System.out.println("任意一个学生:" + findAny);
        //  count:返回流中元素的总个数
        long count = students.stream().count();
        System.out.println("学生总数:" + count);
        // max:返回流中元素最大值
        Student max = students.stream().max(Student::compareTo).get();
        System.out.println("年龄最大学生:" + max);
        // max:返回流中元素最大值
        Student min = students.stream().min(Student::compareTo).get();
        System.out.println("年龄最小学生:" + min);
        System.out.println("--------------------规约操作--------------------");
        System.out.println("学生年龄总和:" + students.stream().map(Student::getAge).reduce(Integer::sum));
        System.out.println("学生年龄最大:" + students.stream().map(Student::getAge).reduce(Integer::max));
        System.out.println("--------------------收集操作--------------------");
        List<Student> list = students.stream().collect(Collectors.toList());
        Set<Student> set = students.stream().collect(Collectors.toSet());
        Map<Integer, String> map = students.stream().collect(Collectors.toMap(Student::getId, Student::getName));
        String joinName = students.stream().map(Student::getName).collect(Collectors.joining(",", "(", ")"));
        // 总数
        students.stream().collect(Collectors.counting());
        // 最大年龄
        students.stream().map(Student::getAge).collect(Collectors.maxBy(Integer::compare)).get();
        // 年龄和
        students.stream().collect(Collectors.summingInt(Student::getAge));
        // 平均年龄
        students.stream().collect(Collectors.averagingDouble(Student::getAge));
        // 信息合集
        DoubleSummaryStatistics statistics = students.stream().collect(Collectors.summarizingDouble(Student::getAge));
        System.out.println("count:" + statistics.getCount() + ",max:" + statistics.getMax() + ",sum:" + statistics.getSum() + ",average:" + statistics.getAverage());
        // 分组
        Map<Integer, List<Student>> collect = students.stream().collect(Collectors.groupingBy(Student::getSex));
        System.out.println(collect);
        //多重分组,先根据性别分再根据年龄分
        Map<Integer, Map<Integer, List<Student>>> typeAgeMap = list.stream().collect(Collectors.groupingBy(Student::getSex, Collectors.groupingBy(Student::getAge)));
        //分区
        //分成两部分,一部分大于20岁,一部分小于等于20岁
        Map<Boolean, List<Student>> partMap = list.stream().collect(Collectors.partitioningBy(v -> v.getAge() > 20));
        //规约
        Integer allAge = list.stream().map(Student::getAge).collect(Collectors.reducing(Integer::sum)).get();
        System.out.println(allAge);
    }
}
ログイン後にコピー

6 へのグループ化の効果を達成することもできます。ストリーム機能

中間操作の遅延実行

複数の中間操作がある場合、複数回循環することはありません。 複数の変換操作は、操作の終了時にのみマージされます。そして1サイクルが完了します

#内部反復

    #条件を満たすデータが見つかった後の反復は続行されません
  • #Flow 終了操作は 1 つだけです。
  • 例外:
  • ストリームはすでに操作されているか、閉じられています

という意味です。ストリームはすでに Closed で操作されています。これは、end 操作を使用すると、

ストリームが閉じられ、 ストリームを再度呼び出すことができないためです。繰り返し呼び出したい場合は、新しいストリームを再度開くことしかできません。ストリーム。

以上がJava8でストリームを使う方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:yisu.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!