Java教程

Java 8 stream(流)

Java在Java 8中提供了一个新的附加程序包,称为java.util.stream。该软件包由类,接口和枚举组成,以允许对元素进行功能样式的操作。您可以通过导入java.util.stream包来使用流。

流提供以下功能:
流不存储元素。它只是通过计算操作的流水线从数据结构,数组或I/O通道等源中传递元素。 流本质上是功能性的。对流执行的操作不会修改其源。例如,对从集合中获取的Stream进行过滤会产生一个不带过滤元素的新Stream,而不是从源集合中删除元素。 流是惰性的,仅在需要时评估代码。 在流的生存期内,流的元素只能访问一次。像Iterator一样,必须生成新的流以重新访问源中的相同元素。
您可以使用流来过滤,收集,打印以及从一种数据结构转换为其他数据结构等。在以下示例中,我们借助流来应用了各种操作。

Java流接口方法

方法 说明
boolean allMatch(Predicate<?super T> predicate) 它将返回此流中与提供的 predicate匹配的所有元素。如果流为空,则返回true,并且不对 predicate求值。
boolean anyMatch(Predicate<?super T> predicate) 它将返回此流中与提供的 predicate匹配的任何元素。如果流为空,则返回false,并且不对 predicate求值。
static <T> Stream.Builder<T> builder() 它返回流的生成器。
R collect(Collector <? super T,A,R> collector) 它使用收集器对该流的元素执行可变的归约操作。收集器封装了用作收集参数的函数(Supplier,BiConsumer,BiConsumer),从而允许重用收集策略和组合收集操作,例如多级分组或分区。
R collect(Supplier supplier, BiConsumer<R,? super T> accumulator, BiConsumer<R,R> combiner) 它对此流的元素执行可变的归约运算。可变归约法是将归约值作为一个可变结果容器(如ArrayList),并且通过更新结果的状态而不是通过替换结果来合并元素的方法。
static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b) 它创建一个延迟连接的流,其元素是第一个流的所有元素,然后是第二个流的所有元素。如果两个输入流都是有序的,则结果流是有序的;如果两个输入流中的任何一个是并行的,则结果流是并行的。关闭结果流后,将同时调用两个输入流的关闭处理程序。
long count() 它返回此流中元素的计数。这是减价的特殊情况。
Stream <T> distant() 它返回由该流的不同元素组成的流(根据Object.equals(Object))。
static <T> Stream<T> empty() 它将返回一个空的顺序流。
Stream<T> filter(Predicate<? super T> predicate) 它返回一个包含与给定 predicate相匹配的流元素的流。
Optional<T> findAny() 它返回描述流中某些元素的Optional;如果流为空,则返回一个空的Optional。
Optional<T> findFirst() 它返回描述此流的第一个元素的Optional;如果流为空,则返回一个空的Optional。如果流没有遇到顺序,则可以返回任何元素。
Stream flatMap(Function<? super T,? extends Stream<? extends R>> mapper) 它返回一个流,该流包括将流中的每个元素替换为通过将提供的映射函数应用于每个元素而生成的映射流的内容而得到的结果。将每个映射流的内容放入此流后,将其关闭。(如果映射的流为null,则使用空流。)
DoubleStream flatMapToDouble(Function<? super T,? extends DoubleStream> mapper) 它返回一个DoubleStream,该结果包含将流中的每个元素替换为通过将提供的映射函数应用于每个元素而生成的映射流的内容而得到的结果。将每个映射流的内容放入该流后,将其关闭。(如果映射的流为null,则使用空流。)
IntStream flatMapToInt(Function<? super T,? extends IntStream> mapper) 它返回一个IntStream,该结果包括将流中的每个元素替换为通过将提供的映射函数应用于每个元素而生成的映射流的内容而得到的结果。将每个映射流的内容放入此流后,将其关闭。(如果映射的流为null,则使用空流。)
LongStream flatMapToLong(Function <?super T,?extended LongStream> mapper) 它返回一个LongStream,该结果包含将流中的每个元素替换为通过将提供的映射函数应用于每个元素而生成的映射流的内容而得到的结果。将每个映射流的内容放入此流后,将其关闭。(如果映射的流为null,则使用空流。)
void forEach(Consumer<?super T> action) 它对此流的每个元素执行一个动作。
void forEachOrdered(Consumer<?super T> action) 如果流具有已定义的遇到顺序,则按流的遇到顺序对此流的每个元素执行操作。
static <T> Stream<T> generate(Supplier<T> s) 它返回一个无限的顺序无序流,其中每个元素由提供的供应商生成。这适用于生成恒定流,随机元素流等。
static <T> Stream<T> iterate(T seed,UnaryOperator<T> f) 它返回通过将函数f迭代应用到初始元素种子而生成的无限顺序有序Stream,该Stream由种子,f(seed),f(f(seed))等组成。
Stream<T> limit(long maxSize) 它返回由该流的元素组成的流,其长度被截断为不超过maxSize。
Stream map(Function<? super T,? extends R> mapper) 它返回一个流,该流包含将给定功能应用于此流的元素的结果。
DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper) 它返回DoubleStream,其中包括将给定函数应用于此流的元素的结果。
IntStream mapToInt(ToIntFunction<? super T> mapper) 它返回一个IntStream,其中包括将给定函数应用于此流的元素的结果。
LongStream mapToLong(ToLongFunction<? super T> mapper) 它返回一个LongStream,其中包括将给定函数应用于此流的元素的结果。
Optional<T> max(Comparator<? super T> comparator) 根据提供的Comparator返回此流的最大元素。这是减少的特殊情况。
Optional<T> min(Comparator<? super T> comparator) 它根据提供的Comparator返回此流的最小元素。这是减少的特殊情况。
boolean noneMatch(Predicate<? super T> predicate) 它返回此流中与提供的 predicate匹配的元素。如果流为空,则返回true,并且不对 predicate求值。
@SafeVarargs static <T> Stream<T> of(T... values) 它返回元素为指定值的顺序有序流。
static <T> Stream<T> of(T t) 它返回一个包含单个元素的顺序Stream。
Stream<T> peek(Consumer<? super T> action) 它返回由该流的元素组成的流,并在从结果流中消耗元素时对每个元素执行附加的操作。
Optional<T> reduce(BinaryOperator<T> accumulator) 它使用关联累加函数对该流的元素进行归约,并返回一个Optional描述归约后的值(如果有)。
T reduce(T identity, BinaryOperator<T> accumulator) 它使用提供的标识值和关联累加函数对该流的元素进行归约,并返回该归约值。
<U> U reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner) 它使用提供的标识,累积和组合功能来对此流的元素进行简化。
Stream <T> skip(long n) 在丢弃流的前n个元素之后,返回由该流的其余元素组成的流。如果此流包含少于n个元素,则将返回空流。
Stream <T> sorted() 它返回由该流的元素组成的流,并根据自然顺序进行排序。如果此流的元素不可比较,则在执行终端操作时可能会抛出java.lang.ClassCastException。
Stream<T> sorted(Comparator<? super T> comparator) 它返回一个由该流的元素组成的流,并根据提供的Comparator对其进行排序。
Object [] toArray() 它返回一个包含此流元素的数组。
<A> A [] toArray(IntFunction <A []>generator) 它使用提供的生成器函数分配包含此流元素的数组,以分配返回的数组以及分区执行或调整大小可能需要的任何其他数组。

Java示例: 不使用Stream过滤集合

在下面的示例中,我们不使用Stream过滤数据。我们在流包发布之前就使用了这种方法。
import java.util.*;
class Product{
  int id;
  String name;
  float price;
  public Product(int id, String name, float price) {
    this.id = id;
    this.name = name;
    this.price = price;
  }
}
public class JavaStreamExample {
  public static void main(String[] args) {
    List<Product> productsList = new ArrayList<Product>();
    //Adding Products
    productsList.add(new Product(1,"HP Laptop",25000f));
    productsList.add(new Product(2,"Dell Laptop",30000f));
    productsList.add(new Product(3,"Lenevo Laptop",28000f));
    productsList.add(new Product(4,"Sony Laptop",28000f));
    productsList.add(new Product(5,"Apple Laptop",90000f));
    List<float> productPriceList = new ArrayList<float>();
    for(Product product: productsList){
      
      // filtering data of list
      if(product.price<30000){
        productPriceList.add(product.price);  // adding price to a productPriceList
      }
    }
    System.out.println(productPriceList); // displaying data
  }
}
输出:
[25000.0, 28000.0, 28000.0]

Java Stream示例: 使用Stream过滤集合

在这里,我们正在使用Stream过滤数据。您可以看到代码已经过优化和维护。流提供了快速执行。
import java.util.*;
import java.util.stream.Collectors;
class Product{
  int id;
  String name;
  float price;
  public Product(int id, String name, float price) {
    this.id = id;
    this.name = name;
    this.price = price;
  }
}
public class JavaStreamExample {
  public static void main(String[] args) {
    List<Product> productsList = new ArrayList<Product>();
    //Adding Products
    productsList.add(new Product(1,"HP Laptop",25000f));
    productsList.add(new Product(2,"Dell Laptop",30000f));
    productsList.add(new Product(3,"Lenevo Laptop",28000f));
    productsList.add(new Product(4,"Sony Laptop",28000f));
    productsList.add(new Product(5,"Apple Laptop",90000f));
    List<float> productPriceList2 =productsList.stream()
                         .filter(p -> p.price > 30000)// filtering data
                         .map(p->p.price)    // fetching price
                         .collect(Collectors.toList()); // collecting as list
    System.out.println(productPriceList2);
  }
}
输出:
[90000.0]

Java Stream迭代示例

您可以使用stream进行任意多次迭代。 Stream提供了预定义的方法来处理您实现的逻辑。在下面的示例中,我们正在迭代,过滤并传递了限制以修复迭代。
import java.util.stream.*;
public class JavaStreamExample {
  public static void main(String[] args){
    Stream.iterate(1, element->element+1)
    .filter(element->element%5==0)
    .limit(5)
    .forEach(System.out::println);
  }
}
输出:
5
10
15
20
25

Java流示例: 过滤和迭代集合

在以下示例中,我们使用filter()方法。在这里,您可以看到代码经过优化并且非常简洁。
import java.util.*;
class Product{
  int id;
  String name;
  float price;
  public Product(int id, String name, float price) {
    this.id = id;
    this.name = name;
    this.price = price;
  }
}
public class JavaStreamExample {
  public static void main(String[] args) {
    List<Product> productsList = new ArrayList<Product>();
    //Adding Products
    productsList.add(new Product(1,"HP Laptop",25000f));
    productsList.add(new Product(2,"Dell Laptop",30000f));
    productsList.add(new Product(3,"Lenevo Laptop",28000f));
    productsList.add(new Product(4,"Sony Laptop",28000f));
    productsList.add(new Product(5,"Apple Laptop",90000f));
    // this is more compact approach for filtering data
    productsList.stream()
                             .filter(product -> product.price == 30000)
                             .forEach(product -> System.out.println(product.name));  
  }
}
输出:
Dell Laptop

Java流示例: Collection中的reduce()方法

此方法采用一系列输入元素,并通过重复操作将它们组合为单个汇总结果。例如,找到数字的总和或将元素累加到列表中。
在下面的示例中,我们使用reduce()方法,该方法用于对所有产品价格进行求和。
import java.util.*;
class Product{
  int id;
  String name;
  float price;
  public Product(int id, String name, float price) {
    this.id = id;
    this.name = name;
    this.price = price;
  }
}
public class JavaStreamExample {
  public static void main(String[] args) {
    List<Product> productsList = new ArrayList<Product>();
    //Adding Products
    productsList.add(new Product(1,"HP Laptop",25000f));
    productsList.add(new Product(2,"Dell Laptop",30000f));
    productsList.add(new Product(3,"Lenevo Laptop",28000f));
    productsList.add(new Product(4,"Sony Laptop",28000f));
    productsList.add(new Product(5,"Apple Laptop",90000f));
    // this is more compact approach for filtering data
    float totalPrice = productsList.stream()
          .map(product->product.price)
          .reduce(0.0f,(sum, price)->sum+price); // accumulating price
    System.out.println(totalPrice);
    // More precise code 
    float totalPrice2 = productsList.stream()
        .map(product->product.price)
        .reduce(0.0f,float::sum);  // accumulating price, by referring method of float class
    System.out.println(totalPrice2);
    
  }
}
输出:
201000.0
201000.0

Java流示例: 使用收集器方法求和

我们还可以使用收集器来计算数字总和。在下面的示例中,我们使用Collectors类及其指定的方法来计算所有产品价格的总和。
import java.util.*;
import java.util.stream.Collectors;
class Product{
  int id;
  String name;
  float price;
  public Product(int id, String name, float price) {
    this.id = id;
    this.name = name;
    this.price = price;
  }
}
public class JavaStreamExample {
  public static void main(String[] args) {
    List<Product> productsList = new ArrayList<Product>();
    //Adding Products
    productsList.add(new Product(1,"HP Laptop",25000f));
    productsList.add(new Product(2,"Dell Laptop",30000f));
    productsList.add(new Product(3,"Lenevo Laptop",28000f));
    productsList.add(new Product(4,"Sony Laptop",28000f));
    productsList.add(new Product(5,"Apple Laptop",90000f));
    // Using Collectors's method to sum the prices.
    double totalPrice3 = productsList.stream()
                      .collect(Collectors.summingDouble(product->product.price));
    System.out.println(totalPrice3);
    
  }
}
输出:
201000.0

Java流示例: 查找最大和最小产品价格

以下示例通过使用流查找最小和最大产品价格。它提供了无需使用命令式方法即可轻松找到价值的方法。
import java.util.*;
class Product{
  int id;
  String name;
  float price;
  public Product(int id, String name, float price) {
    this.id = id;
    this.name = name;
    this.price = price;
  }
}
public class JavaStreamExample {
  public static void main(String[] args) {
    List<Product> productsList = new ArrayList<Product>();
    //Adding Products
    productsList.add(new Product(1,"HP Laptop",25000f));
    productsList.add(new Product(2,"Dell Laptop",30000f));
    productsList.add(new Product(3,"Lenevo Laptop",28000f));
    productsList.add(new Product(4,"Sony Laptop",28000f));
    productsList.add(new Product(5,"Apple Laptop",90000f));
    // max() method to get max Product price 
    Product productA = productsList.stream()
                      .max((product1, product2)-> 
                      product1.price > product2.price ? 1: -1).get();
    
    System.out.println(productA.price);
    // min() method to get min Product price
    Product productB = productsList.stream()
                .max((product1, product2)-> 
                product1.price < product2.price ? 1: -1).get();
    System.out.println(productB.price);
    
  }
}
输出:
90000.0
25000.0

Java流示例: 集合中的count()方法

import java.util.*;
class Product{
  int id;
  String name;
  float price;
  public Product(int id, String name, float price) {
    this.id = id;
    this.name = name;
    this.price = price;
  }
}
public class JavaStreamExample {
  public static void main(String[] args) {
    List<Product> productsList = new ArrayList<Product>();
    //Adding Products
    productsList.add(new Product(1,"HP Laptop",25000f));
    productsList.add(new Product(2,"Dell Laptop",30000f));
    productsList.add(new Product(3,"Lenevo Laptop",28000f));
    productsList.add(new Product(4,"Sony Laptop",28000f));
    productsList.add(new Product(5,"Apple Laptop",90000f));
    // count number of products based on the filter
    long count = productsList.stream()
          .filter(product->product.price<30000)
          .count();
    System.out.println(count);
  }
}
输出:
3
stream允许您以任何形式收集结果。您可以将结果作为集合,列表或映射,并可以对元素进行操作。

Java流示例: 将列表转换为Set

import java.util.*;
import java.util.stream.Collectors;
class Product{
  int id;
  String name;
  float price;
  public Product(int id, String name, float price) {
    this.id = id;
    this.name = name;
    this.price = price;
  }
}
public class JavaStreamExample {
  public static void main(String[] args) {
    List<Product> productsList = new ArrayList<Product>();
    //Adding Products
    productsList.add(new Product(1,"HP Laptop",25000f));
    productsList.add(new Product(2,"Dell Laptop",30000f));
    productsList.add(new Product(3,"Lenevo Laptop",28000f));
    productsList.add(new Product(4,"Sony Laptop",28000f));
    productsList.add(new Product(5,"Apple Laptop",90000f));
    
    // Converting product List into Set
    Set<float> productPriceList = 
      productsList.stream()
      .filter(product->product.price < 30000) // filter product on the base of price
      .map(product->product.price)
      .collect(Collectors.toSet()); // collect it as Set(remove duplicate elements)
    System.out.println(productPriceList);
  }
}
输出:
[25000.0, 28000.0]

Java流示例: 将列表转换为Map</h3>
import java.util.*;
import java.util.stream.Collectors;
class Product{
  int id;
  String name;
  float price;
  public Product(int id, String name, float price) {
    this.id = id;
    this.name = name;
    this.price = price;
  }
}
public class JavaStreamExample {
  public static void main(String[] args) {
    List<Product> productsList = new ArrayList<Product>();
    //Adding Products
    productsList.add(new Product(1,"HP Laptop",25000f));
    productsList.add(new Product(2,"Dell Laptop",30000f));
    productsList.add(new Product(3,"Lenevo Laptop",28000f));
    productsList.add(new Product(4,"Sony Laptop",28000f));
    productsList.add(new Product(5,"Apple Laptop",90000f));
    
    // Converting Product List into a Map
    Map<Integer,String> productPriceMap = 
      productsList.stream()
            .collect(Collectors.toMap</span>(p->p.id, p->p.name));
      
    System.out.println(productPriceMap);
  }
}
输出:
{1=HP Laptop, 2=Dell Laptop, 3=Lenevo Laptop, 4=Sony Laptop, 5=Apple Laptop}

流中的方法引用

import java.util.*;
import java.util.stream.Collectors;
class Product{
  int id;
  String name;
  float price;
  
  public Product(int id, String name, float price) {
    this.id = id;
    this.name = name;
    this.price = price;
  }
    
  public int getId() {
    return id;
  }
  public String getName() {
    return name;
  }
  public float getPrice() {
    return price;
  }
}
public class JavaStreamExample {
  public static void main(String[] args) {
    
    List<Product> productsList = new ArrayList<Product>();
    
    //Adding Products
    productsList.add(new Product(1,"HP Laptop",25000f));
    productsList.add(new Product(2,"Dell Laptop",30000f));
    productsList.add(new Product(3,"Lenevo Laptop",28000f));
    productsList.add(new Product(4,"Sony Laptop",28000f));
    productsList.add(new Product(5,"Apple Laptop",90000f));
    
    List<float> productPriceList = 
        productsList.stream()
                .filter(p -> p.price > 30000) // filtering data
                .map(Product::getPrice)     // fetching price by referring getPrice method
                .collect(Collectors.toList());  // collecting as list
    System.out.println(productPriceList);
  }
}
输出:
[90000.0]
昵称: 邮箱:
Copyright © 2022 立地货 All Rights Reserved.
备案号:京ICP备14037608号-4