📜  Java8 Stream API

📅  最后修改于: 2020-10-13 01:58:47             🧑  作者: Mango

Java 8流

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

Stream提供以下功能:

  • 流不存储元素。它只是通过计算操作的流水线从数据结构,数组或I / O通道等源中传递元素。
  • 流本质上是功能性的。在流上执行的操作不会修改其源。例如,对从集合中获取的流进行过滤会产生一个新的不带过滤元素的流,而不是从源集合中删除元素。
  • Stream是惰性的,仅在需要时才评估代码。
  • 在流的生存期内,流的元素只能访问一次。像Iterator一样,必须生成新的流以重新访问源中的相同元素。

您可以使用流来过滤,收集,print以及从一种数据结构转换为另一种数据结构等。在以下示例中,我们借助流应用了各种操作。

Java Stream接口方法

Methods Description
boolean allMatch(Predicate predicate) It returns all elements of this stream which match the provided predicate. If the stream is empty then true is returned and the predicate is not evaluated.
boolean anyMatch(Predicate predicate) It returns any element of this stream that matches the provided predicate. If the stream is empty then false is returned and the predicate is not evaluated.
static Stream.Builder builder() It returns a builder for a Stream.
R collect(Collector collector) It performs a mutable reduction operation on the elements of this stream using a Collector. A Collector encapsulates the functions used as arguments to collect(Supplier, BiConsumer, BiConsumer), allowing for reuse of collection strategies and composition of collect operations such as multiple-level grouping or partitioning.
R collect(Supplier supplier, BiConsumer accumulator, BiConsumer combiner) It performs a mutable reduction operation on the elements of this stream. A mutable reduction is one in which the reduced value is a mutable result container, such as an ArrayList, and elements are incorporated by updating the state of the result rather than by replacing the result.
static Stream concat(Stream a, Stream b) It creates a lazily concatenated stream whose elements are all the elements of the first stream followed by all the elements of the second stream. The resulting stream is ordered if both of the input streams are ordered, and parallel if either of the input streams is parallel. When the resulting stream is closed, the close handlers for both input streams are invoked.
long count() It returns the count of elements in this stream. This is a special case of a reduction.
Stream distinct() It returns a stream consisting of the distinct elements (according to Object.equals(Object)) of this stream.
static Stream empty() It returns an empty sequential Stream.
Stream filter(Predicate predicate) It returns a stream consisting of the elements of this stream that match the given predicate.
Optional findAny() It returns an Optional describing some element of the stream, or an empty Optional if the stream is empty.
Optional findFirst() It returns an Optional describing the first element of this stream, or an empty Optional if the stream is empty. If the stream has no encounter order, then any element may be returned.
Stream flatMap(Function> mapper) It returns a stream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element. Each mapped stream is closed after its contents have been placed into this stream. (If a mapped stream is null an empty stream is used, instead.)
DoubleStream flatMapToDouble(Function mapper) It returns a DoubleStream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element. Each mapped stream is closed after its contents have placed been into this stream. (If a mapped stream is null an empty stream is used, instead.)
IntStream flatMapToInt(Function mapper) It returns an IntStream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element. Each mapped stream is closed after its contents have been placed into this stream. (If a mapped stream is null an empty stream is used, instead.)
LongStream flatMapToLong(Function mapper) It returns a LongStream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element. Each mapped stream is closed after its contents have been placed into this stream. (If a mapped stream is null an empty stream is used, instead.)
void forEach(Consumer action) It performs an action for each element of this stream.
void forEachOrdered(Consumer action) It performs an action for each element of this stream, in the encounter order of the stream if the stream has a defined encounter order.
static Stream generate(Supplier s) It returns an infinite sequential unordered stream where each element is generated by the provided Supplier. This is suitable for generating constant streams, streams of random elements, etc.
static Stream iterate(T seed,UnaryOperator f) It returns an infinite sequential ordered Stream produced by iterative application of a function f to an initial element seed, producing a Stream consisting of seed, f(seed), f(f(seed)), etc.
Stream limit(long maxSize) It returns a stream consisting of the elements of this stream, truncated to be no longer than maxSize in length.
Stream map(Function mapper) It returns a stream consisting of the results of applying the given function to the elements of this stream.
DoubleStream mapToDouble(ToDoubleFunction mapper) It returns a DoubleStream consisting of the results of applying the given function to the elements of this stream.
IntStream mapToInt(ToIntFunction mapper) It returns an IntStream consisting of the results of applying the given function to the elements of this stream.
LongStream mapToLong(ToLongFunction mapper) It returns a LongStream consisting of the results of applying the given function to the elements of this stream.
Optional max(Comparator comparator) It returns the maximum element of this stream according to the provided Comparator. This is a special case of a reduction.
Optional min(Comparator comparator) It returns the minimum element of this stream according to the provided Comparator. This is a special case of a reduction.
boolean noneMatch(Predicate predicate) It returns elements of this stream match the provided predicate. If the stream is empty then true is returned and the predicate is not evaluated.
@SafeVarargs static Stream of(T… values) It returns a sequential ordered stream whose elements are the specified values.
static Stream of(T t) It returns a sequential Stream containing a single element.
Stream peek(Consumer action) It returns a stream consisting of the elements of this stream, additionally performing the provided action on each element as elements are consumed from the resulting stream.
Optional reduce(BinaryOperator accumulator) It performs a reduction on the elements of this stream, using an associative accumulation function, and returns an Optional describing the reduced value, if any.
T reduce(T identity, BinaryOperator accumulator) It performs a reduction on the elements of this stream, using the provided identity value and an associative accumulation function, and returns the reduced value.
U reduce(U identity, BiFunction accumulator, BinaryOperator combiner) It performs a reduction on the elements of this stream, using the provided identity, accumulation and combining functions.
Stream skip(long n) It returns a stream consisting of the remaining elements of this stream after discarding the first n elements of the stream. If this stream contains fewer than n elements then an empty stream will be returned.
Stream sorted() It returns a stream consisting of the elements of this stream, sorted according to natural order. If the elements of this stream are not Comparable, a java.lang.ClassCastException may be thrown when the terminal operation is executed.
Stream sorted(Comparator comparator) It returns a stream consisting of the elements of this stream, sorted according to the provided Comparator.
Object[] toArray() It returns an array containing the elements of this stream.
A[] toArray(IntFunction generator) It returns an array containing the elements of this stream, using the provided generator function to allocate the returned array, as well as any additional arrays that might be required for a partitioned execution or for resizing.

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 productsList = new ArrayList();
//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 productPriceList = new ArrayList();
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过滤集合

在这里,我们正在使用流过滤数据。您可以看到代码已经过优化和维护。流提供快速执行。

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 productsList = new ArrayList();
//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 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提供了预定义的方法来处理您实现的逻辑。在下面的示例中,我们迭代,过滤并传递了限制以修复迭代。

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 Stream示例:过滤和迭代集合

在下面的示例中,我们使用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 productsList = new ArrayList();
//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 Stream示例: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 productsList = new ArrayList();
//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 Stream示例:使用收集器方法求和

我们还可以使用收集器来计算数值的总和。在下面的示例中,我们使用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 productsList = new ArrayList();
//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 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 productsList = new ArrayList();
//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 Stream示例:Collection中的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 productsList = new ArrayList();
//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

流允许您以各种形式收集结果。您可以将结果作为集合,列表或映射,并可以对元素执行操作。

Java 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 productsList = new ArrayList();

//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 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 Stream示例:将列表转换为Map

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 productsList = new ArrayList();

//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 productPriceMap = 
productsList.stream()
.collect(Collectors.toMap(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 productsList = new ArrayList();

//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 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]