java 8 stream in another stream _java 8 stream – java stream

java 8 stream in another stream

Welcome to Java 8 Stream API tutorial. In the last few java 8 posts, we looked into Java 8 Interface Changes and Functional Interfaces and Lambda Expressions. Today we will look into one of the major API introduced in Java 8 – Java Stream.

Welcome to the Java 8 Stream API tutorial. In the last few articles on Java 8, we looked at Java 8 interface changes and functional interfaces and Lambda expressions . Today, we're going to look at one of the main APIs introduced in Java 8 - Java Stream .

Java 8 流( Java 8 Stream )

  1. Java 8 Stream

    Java 8 streams
  2. Collections and Java Stream

    Collections and Java Streams
  3. Functional Interfaces in Java 8 Stream
    1. Function and BiFunction
    2. Predicate and BiPredicate
    3. Consumer and BiConsumer
    4. Supplier

    Functional interface in Java 8 Stream
    1. function and dual function
    2. Predicates and Double Predicates
    3. consumers and consumers
    4. supplier
  4. java.util.Optional

    java.util.Optional
  5. java.util.Spliterator

    java.util.Spliterator
  6. Java Stream Intermediate and Terminal Operations

    Java Stream intermediate and terminal operations
  7. Java Stream Short Circuiting Operations

    Java Stream short circuit operation
  8. Java Stream Examples
    1. Creating Java Streams
    2. Converting Java Stream to Collection or Array
    3. Java Stream Intermediate Operations
    4. Java Stream Terminal Operations

    Java Stream Example
    1. Create a Java stream
    2. Convert Java Stream to Collection or Array
    3. Java Stream intermediate operations
    4. Java Stream terminal operation
  9. Java 8 Stream API Limitations

    Java 8 Stream API limitations

Java ream ( Java Stream )

Before we look into Java Stream API Examples, let’s see why it was required. Suppose we want to iterate over a list of integers and find out sum of all the integers greater than 10.

Before looking into the Java Stream API example, let's understand why it is needed. Suppose we want to iterate over a list of integers and find the sum of all integers greater than 10.

Prior to Java 8, the approach to do it would be:

Before Java 8, the implemented method was:

private static int sumIterator(List<Integer> list) {
	Iterator<Integer> it = list.iterator();
	int sum = 0;
	while (it.hasNext()) {
		int num = it.next();
		if (num > 10) {
			sum += num;
		}
	}
	return sum;
}

There are three major problems with the above approach:

上述方法存在三个主要问题:

  1. We just want to know the sum of integers but we would also have to provide how the iteration will take place, this is also called external iteration because client program is handling the algorithm to iterate over the list.

    我们只想知道整数的总和,但我们还必须提供迭代的进行方式,这也称为外部迭代,因为客户端程序正在处理算法以遍历列表。
  2. The program is sequential in nature, there is no way we can do this in parallel easily.

    该程序本质上是顺序的,我们无法轻松地并行执行此操作。
  3. There is a lot of code to do even a simple task.

    有很多代码可以完成一个简单的任务。

To overcome all the above shortcomings, Java 8 Stream API was introduced. We can use Java Stream API to implement internal iteration, that is better because java framework is in control of the iteration.

为了克服上述所有缺点,引入了Java 8 Stream API。 我们可以使用Java Stream API来实现内部迭代 ,这更好,因为Java框架控制着迭代。

Internal iteration provides several features such as sequential and parallel execution, filtering based on the given criteria, mapping etc.

内部迭代提供了一些功能,例如顺序和并行执行,基于给定条件的过滤,映射等。

Most of the Java 8 Stream API method arguments are functional interfaces, so lambda expressions work very well with them. Let’s see how can we write above logic in a single line statement using Java Streams.

大多数Java 8 Stream API方法参数都是函数接口,因此lambda表达式可以很好地与它们配合使用。 让我们看看如何使用Java Streams在单行语句中编写以上逻辑。

private static int sumStream(List<Integer> list) {
	return list.stream().filter(i -> i > 10).mapToInt(i -> i).sum();
}

Notice that above program utilizes java framework iteration strategy, filtering and mapping methods and would increase efficiency.

请注意,以上程序利用了Java框架迭代策略,过滤和映射方法,并会提高效率。

First of all we will look into the core concepts of Java 8 Stream API and then we will go through some examples for understanding most commonly used methods.

首先,我们将研究Java 8 Stream API的核心概念,然后我们将通过一些示例来了解最常用的方法。

集合和Java流 (Collections and Java Stream)

A collection is an in-memory data structure to hold values and before we start using collection, all the values should have been populated. Whereas a java Stream is a data structure that is computed on-demand.

集合是用于保存值的内存数据结构,在开始使用集合之前,所有值都应已填充。 而Java Stream是按需计算的数据结构。

Java Stream doesn’t store data, it operates on the source data structure (collection and array) and produce pipelined data that we can use and perform specific operations. Such as we can create a stream from the list and filter it based on a condition.

Java Stream不存储数据,它对源数据结构(集合和数组)进行操作,并生成可以使用并执行特定操作的流水线数据。 例如,我们可以从列表创建流,并根据条件对其进行过滤。

Java Stream operations use functional interfaces, that makes it a very good fit for functional programming using lambda expression. As you can see in the above example that using lambda expressions make our code readable and short.

Java Stream操作使用功能接口,这使其非常适合使用lambda表达式的功能编程。 如您在上面的示例中看到的那样,使用lambda表达式使我们的代码可读性强且简短。

Java 8 Stream internal iteration principle helps in achieving lazy-seeking in some of the stream operations. For example filtering, mapping, or duplicate removal can be implemented lazily, allowing higher performance and scope for optimization.

Java 8 Stream内部迭代原理有助于在某些流操作中实现延迟搜索。 例如,可以延迟实施过滤,映射或重复删除,从而实现更高的性能和优化范围。

Java Streams are consumable, so there is no way to create a reference to stream for future usage. Since the data is on-demand, it’s not possible to reuse the same stream multiple times.

Java流是消耗性的,因此无法创建流引用以供将来使用。 由于数据是按需的,因此不可能多次重用同一数据流。

Java 8 Stream support sequential as well as parallel processing, parallel processing can be very helpful in achieving high performance for large collections.

Java 8 Stream支持顺序以及并行处理,并行处理对于实现大型集合的高性能非常有帮助。

All the Java Stream API interfaces and classes are in the java.util.stream package. Since we can use primitive data types such as int, long in the collections using auto-boxing and these operations could take a lot of time, there are specific classes for primitive types – IntStream, LongStream and DoubleStream.

所有Java Stream API接口和类都在java.util.stream包中。 由于我们可以使用自动装箱在集合中使用基本数据类型(例如int),而且这些操作可能会花费很多时间,因此有一些用于基本类型的特定类IntStreamLongStreamDoubleStream

Java 8 Stream中的功能接口 (Functional Interfaces in Java 8 Stream)

Some of the commonly used functional interfaces in the Java 8 Stream API methods are:

Java 8 Stream API方法中一些常用的功能接口是:

  1. Function and BiFunction: Function represents a function that takes one type of argument and returns another type of argument. Function<T, R> is the generic form where T is the type of the input to the function and R is the type of the result of the function.

    For handling primitive types, there are specific Function interfaces – ToIntFunction, ToLongFunction, ToDoubleFunction, ToIntBiFunction, ToLongBiFunction, ToDoubleBiFunction, LongToIntFunction, LongToDoubleFunction, IntToLongFunction, IntToDoubleFunction etc.

    Some of the Stream methods where Function or it’s primitive specialization is used are:

    • <R> Stream<R> map(Function<? super T, ? extends R> mapper)
    • IntStream mapToInt(ToIntFunction<? super T> mapper) – similarly for long and double returning primitive specific stream.
    • IntStream flatMapToInt(Function<? super T, ? extends IntStream> mapper) – similarly for long and double
    • <A> A[] toArray(IntFunction<A[]> generator)
    • <U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner)

    Function和BiFunction :Function表示一个函数,该函数接受一种类型的参数并返回另一种类型的参数。 Function<T, R>是通用形式,其中T是函数输入的类型,R是函数结果的类型。

    为了处理原始类型,有特定的Function接口ToIntFunctionToLongFunctionToDoubleFunctionToIntBiFunctionToLongBiFunctionToDoubleBiFunctionLongToIntFunctionLongToDoubleFunctionIntToLongFunctionIntToDoubleFunction等。

    使用Function或它的原始专业化Function一些Stream方法是:

    • <R>流<R>映射(功能<?超级T ,?扩展了R>映射器)
    • IntStream mapToInt(ToIntFunction <?super T>映射器)–类似地,对于长且双返回的原始特定流。
    • IntStream flatMapToInt(Function <?super T,?extends IntStream> mapper)–类似地,对于long和double
    • <A> A [] toArray(IntFunction <A []>生成器)
    • <U> U reduce(U标识,BiFunction <U,?super T,U>累加器,BinaryOperator <U>组合器)
  2. Predicate and BiPredicate: It represents a predicate against which elements of the stream are tested. This is used to filter elements from the java stream. Just like Function, there are primitive specific interfaces for int, long and double.

    Some of the Stream methods where Predicate or BiPredicate specializations are used are:

    • Stream<T> filter(Predicate<? super T> predicate)
    • boolean anyMatch(Predicate<? super T> predicate)
    • boolean allMatch(Predicate<? super T> predicate)
    • boolean noneMatch(Predicate<? super T> predicate)

    谓词和BiPredicate :它表示针对流元素进行测试的谓词。 这用于从java流中过滤元素。 就像Function一样,有针对int,long和double的原始特定接口。

    使用PredicateBiPredicate专门化的一些Stream方法是:

    • Stream <T>过滤器(谓词<?super T>谓词)
    • boolean anyMatch(Predicate <?super T>谓词)
    • boolean allMatch(Predicate <?super T>谓词)
    • 布尔值noneMatch(Predicate <?super T>谓词)
  3. Consumer and BiConsumer: It represents an operation that accepts a single input argument and returns no result. It can be used to perform some action on all the elements of the java stream.

    Some of the Java 8 Stream methods where Consumer, BiConsumer or it’s primitive specialization interfaces are used are:

    • Stream<T> peek(Consumer<? super T> action)
    • void forEach(Consumer<? super T> action)
    • void forEachOrdered(Consumer<? super T> action)

    Consumer和BiConsumer :它表示一个接受单个输入参数且不返回结果的操作。 它可用于对java流的所有元素执行某些操作。

    使用ConsumerBiConsumer或其原始专业化接口的一些Java 8 Stream方法是:

    • Stream <T>监视(Consumer <?super T>操作)
    • void forEach(Consumer <?super T>操作)
    • forEachOrdered(Consumer <?super T>操作)无效
  4. Supplier: Supplier represent an operation through which we can generate new values in the stream. Some of the methods in Stream that takes Supplier argument are:
    • public static<T> Stream<T> generate(Supplier<T> s)
    • <R> R collect(Supplier<R> supplier,BiConsumer<R, ? super T> accumulator,BiConsumer<R, R> combiner)

    供应商 :供应商代表一种操作,通过该操作我们可以在流中生成新值。 Stream中带有Supplier参数的一些方法是:
    • 公共static <T> Stream <T> generate(Supplier <T> s)
    • <R> R收集(供应商<R>供应商,BiConsumer <R ,?超级T>累加器,BiConsumer <R,R>组合器)

java.util.Optional (java.util.Optional)

Java Optional is a container object which may or may not contain a non-null value. If a value is present, isPresent() will return true and get() will return the value. Stream terminal operations return Optional object. Some of these methods are:

Java Optional是一个容器对象,可能包含也可能不包含非null值。 如果存在值,则isPresent()将返回true,而get()将返回该值。 流终端操作返回Optional对象。 其中一些方法是:

  • Optional<T> reduce(BinaryOperator<T> accumulator)

    可选的<T> reduce(BinaryOperator <T>累加器)
  • Optional<T> min(Comparator<? super T> comparator)

    可选的<T> min(比较器<?super T>比较器)
  • Optional<T> max(Comparator<? super T> comparator)

    可选的<T> max(Comparator <?super T>比较器)
  • Optional<T> findFirst()

    可选的<T> findFirst()
  • Optional<T> findAny()

    可选的<T> findAny()

java.util.Spliterator (java.util.Spliterator)

For supporting parallel execution in Java 8 Stream API, Spliterator interface is used. Spliterator trySplit method returns a new Spliterator that manages a subset of the elements of the original Spliterator.

为了支持Java 8 Stream API中的并行执行,使用了Spliterator接口。 Spliterator的trySplit方法返回一个新的Spliterator,它管理原始Spliterator元素的子集。

Java Stream中级和终端操作 (Java Stream Intermediate and Terminal Operations)

Java Stream API operations that returns a new Stream are called intermediate operations. Most of the times, these operations are lazy in nature, so they start producing new stream elements and send it to the next operation. Intermediate operations are never the final result producing operations. Commonly used intermediate operations are filter and map.

返回新Stream的Java Stream API操作称为中间操作。 在大多数情况下,这些操作本质上都是惰性的,因此它们开始生成新的流元素并将其发送到下一个操作。 中间操作绝不是最终结果生成操作。 常用的中间操作是filtermap

Java 8 Stream API operations that returns a result or produce a side effect. Once the terminal method is called on a stream, it consumes the stream and after that we can’t use stream. Terminal operations are eager in nature i.e they process all the elements in the stream before returning the result. Commonly used terminal methods are forEach, toArray, min, max, findFirst, anyMatch, allMatch etc. You can identify terminal methods from the return type, they will never return a Stream.

返回结果或产生副作用的Java 8 Stream API操作。 一旦在流上调用了终端方法,它将消耗该流,此后我们将无法使用流。 终端操作本质上是急切的,即它们在返回结果之前处理流中的所有元素。 常用的终端方法是forEachtoArrayminmaxfindFirstanyMatchallMatch等。您可以从返回类型中识别终端方法,它们永远不会返回Stream。

Java Stream短路操作 (Java Stream Short Circuiting Operations)

An intermediate operation is called short circuiting, if it may produce finite stream for an infinite stream. For example limit() and skip() are two short circuiting intermediate operations.

如果中间操作可能产生无限流,则称为短路。 例如limit()skip()是两个短路中间操作。

A terminal operation is called short circuiting, if it may terminate in finite time for infinite stream. For example anyMatch, allMatch, noneMatch, findFirst and findAny are short circuiting terminal operations.

如果终端操作可能在无限时间内终止于无限流,则该操作称为短路。 例如anyMatchallMatchnoneMatchfindFirstfindAny是短路端子操作。

Java Stream示例 (Java Stream Examples)

I have covered almost all the important parts of the Java 8 Stream API. It’s exciting to use this new API features and let’s see it in action with some java stream examples.

我已经介绍了Java 8 Stream API的几乎所有重要部分。 使用这个新的API功能令人兴奋,让我们在一些Java流示例中看到它的实际效果。

创建Java流 (Creating Java Streams)

There are several ways through which we can create a java stream from array and collections. Let’s look into these with simple examples.

我们可以通过几种方法从数组和集合创建Java流。 让我们用简单的例子来研究它们。

  1. We can use Stream.of() to create a stream from similar type of data. For example, we can create Java Stream of integers from a group of int or Integer objects.
    Stream<Integer> stream = Stream.of(1,2,3,4);

    我们可以使用Stream.of()从相似类型的数据创建流。 例如,我们可以根据一组int或Integer对象创建Java整数流。
  2. We can use Stream.of() with an array of Objects to return the stream. Note that it doesn’t support autoboxing, so we can’t pass primitive type array.
    Stream<Integer> stream = Stream.of(new Integer[]{1,2,3,4}); 
    //works fine
    
    Stream<Integer> stream1 = Stream.of(new int[]{1,2,3,4}); 
    //Compile time error, Type mismatch: cannot convert from Stream<int[]> to Stream<Integer>

    我们可以将Stream.of()与Objects数组一起使用以返回流。 请注意,它不支持自动装箱,因此我们无法传递原始类型数组。
  3. We can use Collection stream() to create sequential stream and parallelStream() to create parallel stream.
    List<Integer> myList = new ArrayList<>();
    for(int i=0; i<100; i++) myList.add(i);
    		
    //sequential stream
    Stream<Integer> sequentialStream = myList.stream();
    		
    //parallel stream
    Stream<Integer> parallelStream = myList.parallelStream();

    我们可以使用Collection stream()创建顺序流,并使用parallelStream()创建并行流。
  4. We can use Stream.generate() and Stream.iterate() methods to create Stream.
    Stream<String> stream1 = Stream.generate(() -> {return "abc";});
    Stream<String> stream2 = Stream.iterate("abc", (i) -> i);

    我们可以使用Stream.generate()Stream.iterate()方法创建Stream。
  5. Using Arrays.stream() and String.chars() methods.
    LongStream is = Arrays.stream(new long[]{1,2,3,4});
    IntStream is2 = "abc".chars();

    使用Arrays.stream()String.chars()方法。

将Java Stream转换为Collection或Array (Converting Java Stream to Collection or Array)

There are several ways through which we can get a Collection or Array from a java Stream.

有几种方法可以从Java Stream获取Collection或Array。

  1. We can use java Stream collect() method to get List, Map or Set from stream.
    Stream<Integer> intStream = Stream.of(1,2,3,4);
    List<Integer> intList = intStream.collect(Collectors.toList());
    System.out.println(intList); //prints [1, 2, 3, 4]
    
    intStream = Stream.of(1,2,3,4); //stream is closed, so we need to create it again
    Map<Integer,Integer> intMap = intStream.collect(Collectors.toMap(i -> i, i -> i+10));
    System.out.println(intMap); //prints {1=11, 2=12, 3=13, 4=14}

    我们可以使用java Stream collect()方法从流中获取List,Map或Set。
  2. We can use stream toArray() method to create an array from the stream.
    Stream<Integer> intStream = Stream.of(1,2,3,4);
    Integer[] intArray = intStream.toArray(Integer[]::new);
    System.out.println(Arrays.toString(intArray)); //prints [1, 2, 3, 4]

    我们可以使用流toArray()方法从流中创建一个数组。

Java Stream中间操作 (Java Stream Intermediate Operations)

Let’s look into commonly used java Stream intermediate operations example.

让我们看一下常用的Java Stream中间操作示例。

  1. Stream filter() example: We can use filter() method to test stream elements for a condition and generate filtered list.
    List<Integer> myList = new ArrayList<>();
    for(int i=0; i<100; i++) myList.add(i);
    Stream<Integer> sequentialStream = myList.stream();
    
    Stream<Integer> highNums = sequentialStream.filter(p -> p > 90); //filter numbers greater than 90
    System.out.print("High Nums greater than 90=");
    highNums.forEach(p -> System.out.print(p+" "));
    //prints "High Nums greater than 90=91 92 93 94 95 96 97 98 99 "

    流filter()示例 :我们可以使用filter()方法测试条件的流元素并生成过滤列表。
  2. Stream map() example: We can use map() to apply functions to an stream. Let’s see how we can use it to apply upper case function to a list of Strings.
    Stream<String> names = Stream.of("aBc", "d", "ef");
    System.out.println(names.map(s -> {
    		return s.toUpperCase();
    	}).collect(Collectors.toList()));
    //prints [ABC, D, EF]

    流map()示例 :我们可以使用map()将函数应用于流。 让我们看看如何使用它将大写函数应用于字符串列表。
  3. Stream sorted() example: We can use sorted() to sort the stream elements by passing Comparator argument.
    Stream<String> names2 = Stream.of("aBc", "d", "ef", "123456");
    List<String> reverseSorted = names2.sorted(Comparator.reverseOrder()).collect(Collectors.toList());
    System.out.println(reverseSorted); // [ef, d, aBc, 123456]
    
    Stream<String> names3 = Stream.of("aBc", "d", "ef", "123456");
    List<String> naturalSorted = names3.sorted().collect(Collectors.toList());
    System.out.println(naturalSorted); //[123456, aBc, d, ef]

    流sorted()示例 :我们可以使用sorted()通过传递Comparator参数来对流元素进行排序。
  4. Stream flatMap() example: We can use flatMap() to create a stream from the stream of list. Let’s see a simple example to clear this doubt.
    Stream<List<String>> namesOriginalList = Stream.of(
    	Arrays.asList("Pankaj"), 
    	Arrays.asList("David", "Lisa"),
    	Arrays.asList("Amit"));
    //flat the stream from List<String> to String stream
    Stream<String> flatStream = namesOriginalList
    	.flatMap(strList -> strList.stream());
    
    flatStream.forEach(System.out::println);

    Stream flatMap()示例 :我们可以使用flatMap()从列表流创建流。 让我们看一个简单的例子来消除这个疑问。

Java Stream终端操作 (Java Stream Terminal Operations)

Let’s look at some of the java stream terminal operations example.

让我们看一些Java流终端操作示例。

  1. Stream reduce() example: We can use reduce() to perform a reduction on the elements of the stream, using an associative accumulation function, and return an Optional. Let’s see how we can use it multiply the integers in a stream.
    Stream<Integer> numbers = Stream.of(1,2,3,4,5);
    		
    Optional<Integer> intOptional = numbers.reduce((i,j) -> {return i*j;});
    if(intOptional.isPresent()) System.out.println("Multiplication = "+intOptional.get()); //120

    流reduce()示例 :我们可以使用reduce()通过关联累加函数对流的元素执行归约,然后返回Optional。 让我们看看如何使用它在流中将整数相乘。
  2. Stream count() example: We can use this terminal operation to count the number of items in the stream.
    Stream<Integer> numbers1 = Stream.of(1,2,3,4,5);
    		
    System.out.println("Number of elements in stream="+numbers1.count()); //5

    Stream count()示例 :我们可以使用此终端操作来计算流中的项目数。
  3. Stream forEach() example: This can be used for iterating over the stream. We can use this in place of iterator. Let’s see how to use it for printing all the elements of the stream.
    Stream<Integer> numbers2 = Stream.of(1,2,3,4,5);
    numbers2.forEach(i -> System.out.print(i+",")); //1,2,3,4,5,

    Stream forEach()示例 :这可用于迭代流。 我们可以用它代替迭代器。 让我们看看如何使用它来打印流的所有元素。
  4. Stream match() examples: Let’s see some of the examples for matching methods in Stream API.
    Stream<Integer> numbers3 = Stream.of(1,2,3,4,5);
    System.out.println("Stream contains 4? "+numbers3.anyMatch(i -> i==4));
    //Stream contains 4? true
    
    Stream<Integer> numbers4 = Stream.of(1,2,3,4,5);
    System.out.println("Stream contains all elements less than 10? "+numbers4.allMatch(i -> i<10));
    //Stream contains all elements less than 10? true
    
    Stream<Integer> numbers5 = Stream.of(1,2,3,4,5);
    System.out.println("Stream doesn't contain 10? "+numbers5.noneMatch(i -> i==10));
    //Stream doesn't contain 10? true

    Stream match()示例 :让我们看一些用于Stream API中的匹配方法的示例。
  5. Stream findFirst() example: This is a short circuiting terminal operation, let’s see how we can use it to find the first string from a stream starting with D.
    Stream<String> names4 = Stream.of("Pankaj","Amit","David", "Lisa");
    Optional<String> firstNameWithD = names4.filter(i -> i.startsWith("D")).findFirst();
    if(firstNameWithD.isPresent()){
    	System.out.println("First Name starting with D="+firstNameWithD.get()); //David
    }

    Stream findFirst()示例 :这是一个短路的终端操作,让我们看看如何使用它从以D开头的流中查找第一个字符串。

Java 8 Stream API限制 (Java 8 Stream API Limitations)

Java 8 Stream API brings a lot of new stuffs to work with list and arrays, but it has some limitations too.

Java 8 Stream API带来了许多与列表和数组一起使用的新东西,但是它也有一些限制。

  1. Stateless lambda expressions: If you are using parallel stream and lambda expressions are stateful, it can result in random responses. Let’s see it with a simple program.

    StatefulParallelStream.java

    package com.journaldev.java8.stream;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    import java.util.stream.Stream;
    
    public class StatefulParallelStream {
    
    	public static void main(String[] args) {
    
    		List<Integer> ss = Arrays.asList(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15);
    		List<Integer> result = new ArrayList<Integer>();
    		 
    		Stream<Integer> stream = ss.parallelStream();
    		 
    		stream.map(s -> {
    		        synchronized (result) {
    		          if (result.size() < 10) {
    		            result.add(s);
    		          }
    		        }
    				return s;
    		    }).forEach( e -> {});
    		 System.out.println(result);   
    	}
    }

    If we run above program, you will get different results because it depends on the way stream is getting iterated and we don’t have any order defined for parallel processing. If we use sequential stream, then this problem will not arise.

    无状态Lambda表达式 :如果您使用并行流并且Lambda表达式是有状态的,则可能导致随机响应。 让我们用一个简单的程序看看它。

    StatefulParallelStream.java

    如果我们在上面的程序上运行,您将得到不同的结果,因为它取决于流被迭代的方式,并且我们没有为并行处理定义任何顺序。 如果使用顺序流,则不会出现此问题。

  2. Once a Stream is consumed, it can’t be used later on. As you can see in above examples that every time I am creating a stream.

    流被使用后,以后将无法使用。 如您在上面的示例中看到的,每次创建流时。
  3. There are a lot of methods in Stream API and the most confusing part is the overloaded methods. It makes the learning curve time taking.

    There are many methods in the Stream API, the most confusing part is the overloaded method. It makes the learning curve time consuming.

That’s all for Java 8 Stream example tutorial. I am looking forward to use this feature and make the code readable with better performance through parallel processing.

That's all for the Java 8 Stream example tutorial. I'm looking forward to using this feature and making the code more readable with parallel processing.

Reference: Java Stream API Doc

Reference: Java Stream API Documentation

Translated from: https://www.journaldev.com/2774/java-8-stream

java 8 stream in another stream

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324031231&siteId=291194637