Rumah  >  Artikel  >  Java  >  Ringkasan penggunaan terperinci Stream dalam Java8

Ringkasan penggunaan terperinci Stream dalam Java8

WBOY
WBOYke hadapan
2022-10-05 09:00:272320semak imbas

Artikel ini membawakan anda pengetahuan yang berkaitan tentang Java, yang terutamanya memperkenalkan isu berkaitan tentang penggunaan terperinci Stream The new Stream dalam versi, bersama-sama dengan Lambda yang muncul dalam versi yang sama, memberikan kami koleksi operasi (Koleksi. ) Ini adalah kemudahan yang hebat. Mari kita lihat. Saya harap ia akan membantu semua orang.

Ringkasan penggunaan terperinci Stream dalam Java8

Pembelajaran yang disyorkan: "tutorial video java"

1. Gambaran Keseluruhan

Java 8 sangat berjaya Versi baharu Stream, digabungkan dengan Lambda yang muncul dalam versi yang sama, memberikan kami kemudahan yang hebat dalam mengendalikan koleksi. Strim ialah ahli baharu JDK8, yang membenarkan pemprosesan pengumpulan data secara deklaratif Aliran Strim boleh dianggap sebagai lelaran lanjutan untuk melintasi pengumpulan data. Strim ialah konsep abstrak utama untuk memproses koleksi dalam Java 8. Ia boleh menentukan operasi yang anda ingin lakukan pada koleksi, dan boleh melakukan operasi yang sangat kompleks seperti mencari/menapis/menapis, menyusun, mengagregat dan memetakan data. Menggunakan API Strim untuk mengendalikan data pengumpulan adalah serupa dengan menggunakan SQL untuk melaksanakan pertanyaan pangkalan data. Anda juga boleh menggunakan API Strim untuk melaksanakan operasi secara selari. Ringkasnya, Stream API menyediakan cara yang cekap dan mudah digunakan untuk memproses data.

1. Faedah menggunakan strim

Kod ditulis dalam cara deklaratif, menerangkan perkara yang ingin dicapai, dan bukannya cara untuk melaksanakan operasi.
Beberapa operasi asas boleh disambungkan untuk menyatakan saluran paip pemprosesan data yang kompleks sambil memastikan kod itu jelas dan boleh dibaca.

2. Apakah itu strim

Menghasilkan jujukan elemen daripada sumber yang menyokong operasi pemprosesan data Sumber data boleh berupa koleksi, tatasusunan atau IO sumber.

Dari perspektif operasi, strim berbeza daripada koleksi. Strim tidak menyimpan nilai data; ia adalah mengenai algoritma dan pengiraan.

Jika koleksi digunakan sebagai sumber data strim, mencipta strim tidak akan menyebabkan data mengalir jika operasi penamatan strim memerlukan nilai, strim akan mendapat nilai daripada koleksi; aliran hanya digunakan sekali.

Idea utama strim adalah untuk menangguhkan pengiraan, dan strim tidak mengira nilai sehingga diperlukan.
Ringkasan penggunaan terperinci Stream dalam Java8
Strim boleh dibuat daripada tatasusunan atau koleksi Operasi pada strim dibahagikan kepada dua jenis:

Operasi perantaraan, setiap kali strim baharu dikembalikan, boleh ada berbilang.

Kendalian terminal, setiap aliran hanya boleh melakukan satu operasi terminal Selepas operasi terminal selesai, aliran tidak boleh digunakan lagi. Operasi terminal menghasilkan koleksi atau nilai baharu.

Ciri:

bukan struktur data dan tidak akan menyimpan data.

tidak akan mengubah suai sumber data asal, ia akan menyimpan data yang dikendalikan ke objek lain. (Tempahan: selepas semua, kaedah mengintip boleh mengubah suai elemen dalam aliran)

Penilaian malas Semasa pemprosesan pertengahan aliran, operasi hanya direkodkan dan tidak akan dilaksanakan serta-merta sehingga operasi penamatan dilakukan, barulah pengiraan sebenar akan dijalankan.

2. Klasifikasi

Ringkasan penggunaan terperinci Stream dalam Java8

Stateless: bermaksud bahawa pemprosesan elemen tidak dipengaruhi oleh elemen sebelumnya; operasi Anda hanya boleh meneruskan selepas mendapat semua elemen.

Operasi bukan litar pintas: bermakna semua elemen mesti diproses untuk mendapatkan hasil akhir; syarat yang dihadapi, seperti A || B, Selagi A benar, tidak perlu menilai keputusan B.

3. Penciptaan Strim

Strim boleh dibuat melalui tatasusunan koleksi.

1 Cipta strim dengan koleksi melalui kaedah java.util.Collection.stream()

2. array) kaedah Aliran penciptaan tatasusunan

List<string> list = Arrays.asList("a", "b", "c");// 创建一个顺序流
Stream<string> stream = list.stream();// 创建一个并行流
Stream<string> parallelStream = list.parallelStream();</string></string></string>
3 Gunakan kaedah statik Stream: of(), iterate(), generate()

int[] array={1,3,5,6,8};IntStream stream = Arrays.stream(array);
Hasil keluaran:

Stream<integer> stream = Stream.of(1, 2, 3, 4, 5, 6);
 Stream<integer> stream2 = Stream.iterate(0, (x) -> x + 3).limit(4);stream2.forEach(System.out::println);
 Stream<double> stream3 = Stream.generate(Math::random).limit(3);stream3.forEach(System.out::println);</double></integer></integer>
Perbezaan mudah antara strim dan parallelStream: strim ialah strim berjujukan, dan utas utama menjalankan operasi pada strim secara tertib, manakala parallelStream ialah strim selari dan strim dikendalikan secara dalaman dalam berbilang benang. cara pelaksanaan selari, tetapi premisnya ialah pemprosesan data dalam aliran bukan keperluan Urutan. Contohnya, menapis nombor ganjil dalam koleksi, perbezaan pemprosesan antara keduanya ialah:

0 3 6 90.67961569092719940.19143142088542830.8116932592396652
Jika jumlah data dalam strim cukup besar, strim selari boleh mempercepatkan pemprosesan.


Selain mencipta strim selari secara langsung, anda juga boleh menukar strim berjujukan kepada strim selari melalui selari(): Ringkasan penggunaan terperinci Stream dalam Java8

4 Pengenalan kepada Strim API

Optional<integer> findFirst = list.stream().parallel().filter(x->x>6).findFirst();</integer>

在这里插入Ringkasan penggunaan terperinci Stream dalam Java8描述
Premis: Kelas pekerjaRingkasan penggunaan terperinci Stream dalam Java8

先贴上几个案例,水平高超的同学可以挑战一下:从员工集合中筛选出salary大于8000的员工,并放置到新的集合里。统计员工的最高薪资、平均薪资、薪资之和。将员工按薪资从高到低排序,同样薪资者年龄小者在前。将员工按性别分类,将员工按性别和地区分类,将员工按薪资是否高于8000分为两部分。用传统的迭代处理也不是很难,但代码就显得冗余了,跟Stream相比高下立判。

1 >

Strim juga menyokong elemen traversal dan padanan seperti koleksi, tetapi elemen dalam Strim wujud sebagai jenis Pilihan. Traversal dan pemadanan strim adalah sangat mudah.
static List<person> personList = new ArrayList<person>();private static void initPerson() {
    personList.add(new Person("张三", 8, 3000));
    personList.add(new Person("李四", 18, 5000));
    personList.add(new Person("王五", 28, 7000));
    personList.add(new Person("孙六", 38, 9000));}</person></person>
// import已省略,请自行添加,后面代码亦是
 
public class StreamTest {
  public static void main(String[] args) {
        List<integer> list = Arrays.asList(7, 6, 9, 3, 8, 2, 1);
 
        // 遍历输出符合条件的元素
        list.stream().filter(x -> x > 6).forEach(System.out::println);
        // 匹配第一个
        Optional<integer> findFirst = list.stream().filter(x -> x > 6).findFirst();
        // 匹配任意(适用于并行流)
        Optional<integer> findAny = list.parallelStream().filter(x -> x > 6).findAny();
        // 是否包含符合特定条件的元素
        boolean anyMatch = list.stream().anyMatch(x -> x <h3>2、按条件匹配filter</h3>
<p><img src="https://img.php.cn/upload/article/000/000/067/c32799257ddfee7ae65dfaf7bce4b27c-5.png" alt="在这里插入Ringkasan penggunaan terperinci Stream dalam Java8描述"></p>
<p><strong>(1)筛选员工中已满18周岁的人,并形成新的集合</strong></p>
<pre class="brush:php;toolbar:false">/**
 * 筛选员工中已满18周岁的人,并形成新的集合
 * @思路
 * List<person> list = new ArrayList<person>();
 * for(Person person : personList) {
 *     if(person.getAge() >= 18) {
 *          list.add(person);
 *     }
 * }
 */
private static void filter01() {
    initPerson();
    List<person> collect = personList.stream().filter(x -> x.getAge()>=18).collect(Collectors.toList());
    System.out.println(collect);}</person></person></person>

在这里插入Ringkasan penggunaan terperinci Stream dalam Java8描述
(2)自定义条件匹配
Ringkasan penggunaan terperinci Stream dalam Java8

3、聚合max、min、count

Ringkasan penggunaan terperinci Stream dalam Java8

(1)获取String集合中最长的元素

/**
 * 获取String集合中最长的元素
 * @思路
 * List<string> list = Arrays.asList("zhangsan", "lisi", "wangwu", "sunliu");
 * String max = "";
 * int length = 0;
 * int tempLength = 0;
 * for(String str : list) {
 *     tempLength = str.length();
 *     if(tempLength > length) {
 *         length  = str.length();
 *         max = str;
 *      }
 * }
 * @return zhangsan
 */
private static void test02() {
    List<string> list = Arrays.asList("zhangsan", "lisi", "wangwu", "sunliu");
    Comparator super String> comparator = Comparator.comparing(String::length);
    Optional<string> max = list.stream().max(comparator);
    System.out.println(max);}</string></string></string>

Ringkasan penggunaan terperinci Stream dalam Java8
(2)获取Integer集合中的最大值

//获取Integer集合中的最大值
private static void test05() {
    List<integer> list = Arrays.asList(1, 17, 27, 7);
    Optional<integer> max = list.stream().max(Integer::compareTo);
    // 自定义排序
    Optional<integer> max2 = list.stream().max(new Comparator<integer>() {
        @Override
        public int compare(Integer o1, Integer o2) {
            return o1.compareTo(o2);
        }
    });
    System.out.println(max2);}</integer></integer></integer></integer>

Ringkasan penggunaan terperinci Stream dalam Java8

//获取员工中年龄最大的人
private static void test06() {
    initPerson();
    Comparator super Person> comparator = Comparator.comparingInt(Person::getAge);
    Optional<person> max = personList.stream().max(comparator);
    System.out.println(max);}</person>

(3)获取员工中年龄最大的人
在这里插入Ringkasan penggunaan terperinci Stream dalam Java8描述
4)计算integer集合中大于10的元素的个数
在这里插入Ringkasan penggunaan terperinci Stream dalam Java8描述

4、map与flatMap

map:接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。

flatMap:接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。

Ringkasan penggunaan terperinci Stream dalam Java8

(1)字符串大写
Ringkasan penggunaan terperinci Stream dalam Java8
(2)整数数组每个元素+3

/**
 * 整数数组每个元素+3
 * @思路
 * List<integer> list = Arrays.asList(1, 17, 27, 7);
   List<integer> list2 = new ArrayList<integer>();
   for(Integer num : list) {
      list2.add(num + 3);
   }
   @return [4, 20, 30, 10]
 */
private static void test09() {
    List<integer> list = Arrays.asList(1, 17, 27, 7);
    List<integer> collect = list.stream().map(x -> x + 3).collect(Collectors.toList());
    System.out.println(collect);}</integer></integer></integer></integer></integer>

(3)公司效益好,每人涨2000

/**
 * 公司效益好,每人涨2000
 *
 */
private static void test10() {
    initPerson();
    List<person> collect = personList.stream().map(x -> {
        x.setAge(x.getSalary()+2000);
        return x;
    }).collect(Collectors.toList());
    System.out.println(collect);}</person>

(4)将两个字符数组合并成一个新的字符数组

/**
 * 将两个字符数组合并成一个新的字符数组
 *
 */
private static void test11() {
    String[] arr = {"z, h, a, n, g", "s, a, n"};
    List<string> list = Arrays.asList(arr);
    System.out.println(list);
    List<string> collect = list.stream().flatMap(x -> {
        String[] array = x.split(",");
        Stream<string> stream = Arrays.stream(array);
        return stream;
    }).collect(Collectors.toList());
    System.out.println(collect);}</string></string></string>

(5)将两个字符数组合并成一个新的字符数组

/**
 * 将两个字符数组合并成一个新的字符数组
 * @return [z,  h,  a,  n,  g, s,  a,  n]
 */
private static void test11() {
    String[] arr = {"z, h, a, n, g", "s, a, n"};
    List<string> list = Arrays.asList(arr);
    List<string> collect = list.stream().flatMap(x -> {
        String[] array = x.split(",");
        Stream<string> stream = Arrays.stream(array);
        return stream;
    }).collect(Collectors.toList());
    System.out.println(collect);}</string></string></string>

5、规约reduce

归约,也称缩减,顾名思义,是把一个流缩减成一个值,能实现对集合求和、求乘积和求最值操作。
Ringkasan penggunaan terperinci Stream dalam Java8
(1)求Integer集合的元素之和、乘积和最大值

/**
 * 求Integer集合的元素之和、乘积和最大值
 *
 */
private static void test13() {
    List<integer> list = Arrays.asList(1, 2, 3, 4);
    //求和
    Optional<integer> reduce = list.stream().reduce((x,y) -> x+ y);
    System.out.println("求和:"+reduce);
    //求积
    Optional<integer> reduce2 = list.stream().reduce((x,y) -> x * y);
    System.out.println("求积:"+reduce2);
    //求最大值
    Optional<integer> reduce3 = list.stream().reduce((x,y) -> x>y?x:y);
    System.out.println("求最大值:"+reduce3);}</integer></integer></integer></integer>

(2)求所有员工的工资之和和最高工资

/*
 * 求所有员工的工资之和和最高工资
 */
private static void test14() {
    initPerson();
    Optional<integer> reduce = personList.stream().map(Person :: getSalary).reduce(Integer::sum);
    Optional<integer> reduce2 = personList.stream().map(Person :: getSalary).reduce(Integer::max);
    System.out.println("工资之和:"+reduce);
    System.out.println("最高工资:"+reduce2);}</integer></integer>

6、收集(toList、toSet、toMap)

取出大于18岁的员工转为map

/**
 * 取出大于18岁的员工转为map
 *
 */
private static void test15() {
    initPerson();
    Map<string> collect = personList.stream().filter(x -> x.getAge() > 18).collect(Collectors.toMap(Person::getName, y -> y));
    System.out.println(collect);}</string>

7、collect

Collectors提供了一系列用于数据统计的静态方法:

计数: count

平均值: averagingInt、 averagingLong、 averagingDouble

最值: maxBy、 minBy

求和: summingInt、 summingLong、 summingDouble

统计以上所有: summarizingInt、 summarizingLong、 summarizingDouble

/**
 * 统计员工人数、平均工资、工资总额、最高工资
 */
private static void test01(){
    //统计员工人数
    Long count = personList.stream().collect(Collectors.counting());
    //求平均工资
    Double average = personList.stream().collect(Collectors.averagingDouble(Person::getSalary));
    //求最高工资
    Optional<integer> max = personList.stream().map(Person::getSalary).collect(Collectors.maxBy(Integer::compare));
    //求工资之和
    Integer sum = personList.stream().collect(Collectors.summingInt(Person::getSalary));
    //一次性统计所有信息
    DoubleSummaryStatistics collect = personList.stream().collect(Collectors.summarizingDouble(Person::getSalary));
    System.out.println("统计员工人数:"+count);
    System.out.println("求平均工资:"+average);
    System.out.println("求最高工资:"+max);
    System.out.println("求工资之和:"+sum);
    System.out.println("一次性统计所有信息:"+collect);}</integer>

8、分组(partitioningBy/groupingBy)

分区:将stream按条件分为两个 Map,比如员工按薪资是否高于8000分为两部分。

分组:将集合分为多个Map,比如员工按性别分组。有单级分组和多级分组。
Ringkasan penggunaan terperinci Stream dalam Java8

将员工按薪资是否高于8000分为两部分;将员工按性别和地区分组

public class StreamTest {
  public static void main(String[] args) {
    personList.add(new Person("zhangsan",25, 3000, "male", "tieling"));
        personList.add(new Person("lisi",27, 5000, "male", "tieling"));
        personList.add(new Person("wangwu",29, 7000, "female", "tieling"));
        personList.add(new Person("sunliu",26, 3000, "female", "dalian"));
        personList.add(new Person("yinqi",27, 5000, "male", "dalian"));
        personList.add(new Person("guba",21, 7000, "female", "dalian"));
 
    // 将员工按薪资是否高于8000分组
        Map<boolean>> part = personList.stream().collect(Collectors.partitioningBy(x -> x.getSalary() > 8000));
        // 将员工按性别分组
        Map<string>> group = personList.stream().collect(Collectors.groupingBy(Person::getSex));
        // 将员工先按性别分组,再按地区分组
        Map<string>>> group2 = personList.stream().collect(Collectors.groupingBy(Person::getSex, Collectors.groupingBy(Person::getArea)));
        System.out.println("员工按薪资是否大于8000分组情况:" + part);
        System.out.println("员工按性别分组情况:" + group);
        System.out.println("员工按性别、地区:" + group2);
  }}</string></string></boolean>

9、连接joining

joining可以将stream中的元素用特定的连接符(没有的话,则直接连接)连接成一个字符串。
Ringkasan penggunaan terperinci Stream dalam Java8

10、排序sorted

将员工按工资由高到低(工资一样则按年龄由大到小)排序

private static void test04(){
    // 按工资升序排序(自然排序)
    List<string> newList = personList.stream().sorted(Comparator.comparing(Person::getSalary)).map(Person::getName)
            .collect(Collectors.toList());
    // 按工资倒序排序
    List<string> newList2 = personList.stream().sorted(Comparator.comparing(Person::getSalary).reversed())
            .map(Person::getName).collect(Collectors.toList());
    // 先按工资再按年龄升序排序
    List<string> newList3 = personList.stream()
            .sorted(Comparator.comparing(Person::getSalary).thenComparing(Person::getAge)).map(Person::getName)
            .collect(Collectors.toList());
    // 先按工资再按年龄自定义排序(降序)
    List<string> newList4 = personList.stream().sorted((p1, p2) -> {
        if (p1.getSalary() == p2.getSalary()) {
            return p2.getAge() - p1.getAge();
        } else {
            return p2.getSalary() - p1.getSalary();
        }
    }).map(Person::getName).collect(Collectors.toList());
 
    System.out.println("按工资升序排序:" + newList);
    System.out.println("按工资降序排序:" + newList2);
    System.out.println("先按工资再按年龄升序排序:" + newList3);
    System.out.println("先按工资再按年龄自定义降序排序:" + newList4);}</string></string></string></string>

11、提取/组合

流也可以进行合并、去重、限制、跳过等操作。

private static void test05(){
    String[] arr1 = { "a", "b", "c", "d" };
    String[] arr2 = { "d", "e", "f", "g" };
    Stream<string> stream1 = Stream.of(arr1);
    Stream<string> stream2 = Stream.of(arr2);
    // concat:合并两个流 distinct:去重
    List<string> newList = Stream.concat(stream1, stream2).distinct().collect(Collectors.toList());
    // limit:限制从流中获得前n个数据
    List<integer> collect = Stream.iterate(1, x -> x + 2).limit(10).collect(Collectors.toList());
    // skip:跳过前n个数据
    List<integer> collect2 = Stream.iterate(1, x -> x + 2).skip(1).limit(5).collect(Collectors.toList());
 
    System.out.println("流合并:" + newList);
    System.out.println("limit:" + collect);
    System.out.println("skip:" + collect2);}</integer></integer></string></string></string>

12、读取文件的流操作

Ringkasan penggunaan terperinci Stream dalam Java8

13、计算两个list中的差集

//计算两个list中的差集
List<string> reduce1 = allList.stream().filter(item -> !wList.contains(item)).collect(Collectors.toList());</string>

推荐学习:《java视频教程

Atas ialah kandungan terperinci Ringkasan penggunaan terperinci Stream dalam Java8. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:csdn.net. Jika ada pelanggaran, sila hubungi admin@php.cn Padam