Java 8流

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

  • 流不存储元素。它只是通过计算操作的流水线从数据结构, 数组或I / O通道等源中传递元素。
  • 流本质上是功能性的。对流执行的操作不会修改其源。例如, 对从集合中获取的流进行过滤会产生一个新的不带过滤元素的流, 而不是从源集合中删除元素。
  • Stream是惰性的, 仅在需要时才评估代码。
  • 在流的生存期内, 流的元素只能访问一次。像Iterator一样, 必须生成新的流以重新访问源中的相同元素。
你可以使用流来过滤, 收集, 打印以及从一种数据结构转换为其他数据结构等。在以下示例中, 我们借助流来应用了各种操作。
Java Stream接口方法
方法 描述
boolean allMatch(Predicate < ?super T> 谓词) 它返回此流中与提供的谓词匹配的所有元素。如果流为空, 则返回true, 并且不评估谓词。
boolean anyMatch(Predicate < ?super T> 谓词) 它返回此流中与提供的谓词匹配的任何元素。如果流为空, 则返回false, 并且不对谓词求值。
静态< T> Stream.Builder < T> builder() 它返回流的构建器。
< R, A> R收集器(Collector < ?super T, A, R> 收集器) 它使用收集器对此流的元素执行可变还原操作。收集器封装了用作收集参数的函数(供应商, BiConsumer, BiConsumer), 从而允许重用收集策略并组成收集操作, 例如多级分组或分区。
< R> R收集(供应商< R> 供应商, BiConsumer < R , ? super T> 累加器, BiConsumer < R, R> 组合器) 它对该流的元素执行可变还原操作。可变归约是其中归约值是一个可变结果容器(例如ArrayList), 并且通过更新结果的状态而不是通过替换结果来合并元素。
静态< T> Stream < T> concat(Stream < ?扩展T> a, Stream < ?扩展T> b) 它创建一个延迟串联的流, 其元素是第一个流的所有元素, 然后是第二个流的所有元素。如果两个输入流都是有序的, 则结果流是有序的;如果两个输入流中的任何一个是并行的, 则结果流是并行的。关闭结果流后, 将同时调用两个输入流的关闭处理程序。
long count() 它返回此流中的元素计数。这是减少的特殊情况。
Stream < T> exclude() 它返回一个由该流的不同元素组成的流(根据Object.equals(Object))。
静态< T> 流< T> empty() 它返回一个空的顺序Stream。
Stream < T> 过滤器(谓词< ?super T> 谓词) 它返回一个流, 该流包含与给定谓词匹配的该流的元素。
Optional< T> findAny() 它返回描述流中某些元素的Optional, 如果流为空, 则返回空的Optional。
Optional< T> findFirst() 它返回描述此流的第一个元素的Optional;如果流为空, 则返回一个空的Optional。如果流没有遇到顺序, 则可以返回任何元素。
< R> Stream < R> flatMap(功能< ?超级T , ?扩展Stream < ?扩展R > > 映射器) 它返回一个流, 该流包括将流中的每个元素替换为通过将提供的映射函数应用于每个元素而生成的映射流的内容而得到的结果。将每个映射流的内容放入该流后, 将其关闭。 (如果映射的流为null, 则使用空流。)
DoubleStream flatMapToDouble(Function < ?super T, ?extended DoubleStream> 映射器) 它返回一个DoubleStream, 该结果包含将流中的每个元素替换为通过将提供的映射函数应用于每个元素而生成的映射流的内容而得到的结果。将每个映射流的内容放入该流后, 将其关闭。 (如果映射的流为null, 则使用空流。)
IntStream flatMapToInt(Function < ?super T, ?extended IntStream> 映射器) 它返回一个IntStream, 该结果由将流中的每个元素替换为通过将提供的映射函数应用于每个元素而生成的映射流的内容而得到的结果。将每个映射流的内容放入该流后, 将其关闭。 (如果映射的流为null, 则使用空流。)
LongStream flatMapToLong(Function < ?super T, ?extended LongStream> 映射器) 它返回一个LongStream, 该结果包含将流中的每个元素替换为通过将提供的映射函数应用于每个元素而生成的映射流的内容而得到的结果。将每个映射流的内容放入该流后, 将其关闭。 (如果映射的流为null, 则使用空流。)
void forEach(Consumer < ?super T> 操作) 它对此流的每个元素执行一个动作。
forEachOrdered(Consumer < ?super T> 操作)无效 如果流具有已定义的遇到顺序, 则它将按流的遇到顺序对此流的每个元素执行操作。
静态< T> Stream < T> generate(Supplier < T> s) 它返回无限顺序无序流, 其中每个元素由提供的供应商生成。这适用于生成恒定流, 随机元素流等。
静态< T> 流< T> 迭代(T种子, 一元运算符< T> f) 它返回通过将函数f迭代应用到初始元素种子而产生的无限顺序有序Stream, 该Stream由种子, f(seed), f(f(seed))等组成。
Stream < T> 限制(长为maxSize) 它返回由该流的元素组成的流, 其长度被截断为不超过maxSize。
< R> 流< R> 映射(功能< ?超级T , ?扩展了R> 映射器) 它返回一个流, 该流包括将给定功能应用于此流的元素的结果。
DoubleStream mapToDouble(ToDoubleFunction < ?super T> 映射器) 它返回一个DoubleStream, 其中包括将给定函数应用于此流的元素的结果。
IntStream mapToInt(ToIntFunction < ?super T> 映射器) 它返回一个IntStream, 其中包括将给定函数应用于此流的元素的结果。
LongStream mapToLong(ToLongFunction < ?super T> 映射器) 它返回一个LongStream, 其中包括将给定函数应用于此流的元素的结果。
可选的< T> max(Comparator < ?super T> 比较器) 它根据提供的Comparator返回此流的最大元素。这是减少的特殊情况。
可选的< T> min(比较器< ?super T> 比较器) 它根据提供的Comparator返回此流的最小元素。这是减少的特殊情况。
布尔值noneMatch(Predicate < ?super T> 谓词) 它返回此流的元素匹配提供的谓词。如果流为空, 则返回true, 并且不评估谓词。
@SafeVarargs静态< T> 流< T> of(T … values) 它返回一个顺序有序的流, 其元素为指定值。
(T t)的静态< T> Stream < T> 它返回一个包含单个元素的顺序Stream。
Stream < T> 监视(Consumer < ?super T> 操作) 它返回由该流的元素组成的流, 并在从结果流中消耗元素时对每个元素执行附加的操作。
可选的< T> reduce(BinaryOperator < T> 累加器) 它使用关联的累加函数对此流的元素进行归约, 并返回一个Optional描述归约值(如果有)。
T reduce(T标识, BinaryOperator < T> 累加器) 它使用提供的标识值和关联累加函数对此流的元素执行归约, 然后返回该归约值。
< U> U reduce(U标识, BiFunction < U 、? super T, U> 累加器, BinaryOperator < U> 组合器) 使用提供的标识, 累积和组合功能, 它对此流的元素进行简化。
流< T> 跳过(长n) 在丢弃流的前n个元素之后, 它将返回由该流的其余元素组成的流。如果此流包含少于n个元素, 则将返回空流。
Stream< T> sorted() 它返回一个由该流的元素组成的流, 并根据自然顺序进行排序。如果此流的元素不可比较, 则在执行终端操作时可能会引发java.lang.ClassCastException。
Stream < T> 已排序(Comparator < ?super T> 比较器) 它返回一个由该流的元素组成的流, 并根据提供的Comparator对其进行排序。
Object[] toArray() 它返回一个包含此流元素的数组。
< A> A [] toArray(IntFunction < A []> 生成器) 它使用提供的生成器函数分配返回的数组以及分区执行或调整大小可能需要的任何其他数组, 从而返回包含该流元素的数组。
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)); 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过滤集合
在这里, 我们正在使用流过滤数据。你可以看到代码已经过优化和维护。流提供快速执行。
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提供了预定义的方法来处理你实现的逻辑。在下面的示例中, 我们正在迭代, 过滤并传递了限制以修复迭代。
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< 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 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< 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 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< 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); } }

【Java 8流】输出:
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< 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 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< 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

流允许你以各种形式收集结果。你可以将结果作为集合, 列表或映射, 并可以对元素执行操作。
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< 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 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< 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(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]

    推荐阅读