Operation of the stream
The use of streams typically consists of three things:
A data source to execute a query;
An intermediate operation chain, forming a flow of the pipeline;
A terminal operation, execution pipeline, and the ability to generate results
Intermediate operation
Operation |
type |
return type |
Operating Parameters |
function Descriptor |
Filter |
Middle |
Stream |
predicate |
Boolean, T |
Map |
Middle |
Stream |
Function |
T->r |
Limit |
Middle |
Stream |
|
|
Sorted |
Middle |
Stream |
Comparator |
(t,t)->int |
Distinct |
Middle |
Stream |
|
|
Terminal operations
Operation |
type |
Purpose |
Foreach |
Terminal |
Consume each element in the stream and apply a lambda to it. This operation returns void |
Count |
Terminal |
Returns the number of elements in the stream, which returns a long |
Collect |
Terminal |
The flow is normalized to a set, such as List,map or even an integer. |
Using stream filtering
Out of the filter, the stream also supports a method called DISTINCT, which returns a stream of elements that are different (based on the hashcode of the elements generated by the stream and the Equals method). For example, the following code filters out all the even numbers in the list and ensures that there are no duplicates
List<Integer> numbers = Arrays.asList(1,2,1,3,3,2,4);numbers.stream() .filter(i -> i%2 ==0) .distinct() .forEach(System.out::println);
Cutoff
The stream supports the limit (n) method, which returns a stream that does not exceed a given length.
List<Dish> dishes = menu.stream().filter(d->d.getCalories()>300).limit(3).collect(toList());
Skip Element
The stream also supports the Skip (n) method, which returns a stream that discards the first n elements.
List<Dish> dishes = menu.stream().filter(d->d.getCalories()>300).skip(2).collect(toList());
Mapping each element in a convection application function
For example: If you want to find out how long the name of each dish is, then the following:
List<Integer> dishNameLengths = menu.stream().map(Dish::getname).map(String::length).collect(toList())
Flattening of the flow
For example: Given a list of words ["Hello", "World"], you want to return the list ["H", "E", "L", "L", "O", "w", "O", "R", "L", "D"]
Using the above may be:
words.stream().map(word->word.split("")).distinct().collect(toList());
The problem with this method is that the lambda passed to the map method returns a string[] (String list) for each word, so that the stream returned by map is actually stream< string[] > type. What you really want is a stream. < String > to represent a character stream
1. Try using map and Arrays.stream ()
String[] arrayOfWords = {"GoodBye","World"};Stream< String> streamOfWords = Arrays.stream(arrayOfWords);
2. Using Flatmap
String[] arrayOfWords = {"GoodBye","World"}; Stream< String> streamOfWords = Arrays.stream(arrayOfWords); List<String[]> collect = streamOfWords.map(m -> m.split("")).collect(toList()); System.out.println(collect);
Example 2:
Given list [3,4] and [+], return [(1,3), (1,4), (2,3) ...]
list<integer> integers = Arrays. (1 , 2 , 3 ); List<integer> integers1 = Arrays. aslist (3 , 4 ); List<int []> collect = integers. stream () . flatmap (I-integers1. stream () . map (J-new int []{i, J})) . collect (tolist ()); Collect. foreach (i, {String s = Arrays. (i); System. out . println (s); });
Example 3:
To extend the previous example, only the number pairs that are combined to be 3 are returned.
List<Integer> int1 = Arrays.asList(123); List<Integer> int2 = Arrays.asList(34); List<int[]> collect = int1.stream().flatMap(i -> int2.stream().filter30).mapnewint[]{i, j})).collect(toList()); System.out.println(collect);
Finding and matching matches 1. Check if the predicate matches at least one element
The AnyMatch method can answer "if there is an element in the stream that matches the given predicate"
if(menu.stream().anyMatch(Dish::isVegetarian)){ System.out.println("The menu is vegetarian friendly!!"); }
2. Check if the predicate matches all elements
For example: Use Allmatch to see if the food is healthy
boolean isHealthy = menu.stream().allMatch(d->d.getCalories()<1000);
3. Ensure that no elements in the stream match the given predicate nonematch
boolean isHealthy = menu.stream().noneMatch(d->d.getCalories()<1000);
Finding the Findany method will return any element in the current stream
Optional<Dish> dish = menu.stream().filter(Dish::isVegetarian).findAny();
Find first element
List<Integer> someNumbers = Arrays.asList(1,2,3,4,5);Optional<Integer> firstSquareDivisibleByThree = someNumbers.stream() .map(x->x*x) .filter(x->x%30) .findFirst();
Sum reduction of the normalized elements
Reduce accepts two parameters
An initial value, here is 0
A binaryoperator< T > to combine two elements to produce a new value, here we use Lambda (A, b)->a+b;
int sum = numbers.stream().reduce(0,(a,b)->a+b);
Multiply:
int product = numbers.stream().reduce(1,(a,b)->a*b);
In Java 8, the integer class already has a static sum method to sum the two numbers
int num=numbers.stream().reduce(0,Integer::sum);
Maximum value:
Optional<Integer> max = numbers.stream().reduce(Intger::max)
Minimum value:
Optional<Integer> min = numbers.stream().reduce(Integer::min);
Numerical flow primitive type flow specificity
Java 8 introduces three primitive type specialization stream interfaces to specifically support the method of handling numerical flows: Intstream. Doublestream and Longstream,.
The elements in the stream are Int,long, double, thus avoiding the implied packing cost
1. Mapping to a numerical stream
The usual method of translating the flow into a special version is maptoint,maptodouble, Maptolong.
int calaories = menu.stream() .mapToInt(Dish::getCalories)//返回一个IntStream .sum();
2. Convert back to's really into flow boxed
IntStream intStream = menu.stream().mapToInt(Dish::getCalories);Stream<Integer> stream = intStream.boxed();
3. Default Value Optionalint
There is a default value of 0 in Intstream, so in order to solve the problem of finding the maximum or minimum value, use optional original type Special version: Optionalint,
Optionaldouble,optionallong.
For example: to find the largest element in Intstream, you can call the Max method, which returns a optionalint:
OptionalInt maxCalories = menu.stream() .mapToInt(Dish::getCalories) .max();//如果没有最大值的话,可默认一个最大值int max = maxCalories.orElse(1);
4. Range of values
If you want to generate all numbers from 1 to 100. Java8 introduces two static methods that can be used with Intstream and longstream to help generate this range: Range and rangeclosed. Both methods accept the starting value for the first parameter, and the second parameter accepts the end value. But range does not contain an end value, and rangeclosed contains an end value
IntStream evenNumbers = IntStream.rangeClosed(1,100) .filter20);//一个从1到100的偶数流System.out.println(evenNumbers.count());//从1到100有50个偶数
Build stream creates a stream from a value
You can use the static method Stream.of to create a stream by displaying values. It can accept any number of parameters
Strean<String> stream = Stream.of("java 8","Lambdas ","In ","Action");stream.map(String::toUpperCase).forEach(System.out::println);//使用empty得到一个空流Stream<String> emptySteam = Stream.empty();
Create a stream from an array
int[] numbers = {2,3,4,11,13};int sum = Arrays.stream(numbers).sum();
Stream generated by file
long0;try(Stream<String> lines = Files.lines(Paths.get("data.txt"),Charset.defaultCharset())){ uniqueWords = lines.flatMap(line -> Arrays.stream(line.split(" "))) .distinct() .count();}catch(IOException e){ }
Generating a stream from a function: creating an infinite stream
Stream.iterate and Stream.generate, in general, should use Limit (n) to restrict this flow to avoid printing an infinite number of values
1. Iteration
Stream.iterate(0,n -> n+2) .limit(10) .forEach(System.out::println);
2. Build
Similar to the iterate method, the Generate method can generate an infinite stream. However, generate does not apply the function to each newly generated value in turn. It takes a supplier< T > type lambda to provide a new value
Stream.generate(Math::random) .limit(5) .forEach(System.out::println);
//The code below is out of quiet a FibonacciIntsupplier fib =New Intsuppleir(){Private intPrevious =0;Private intCurrent =1; Public int Getasint(){intOldprevious = This.previous;intNextValue = This.previous+ This. Current; This.previous= This. Current; This. Current= NextValue;returnoldprevious; }};intstream.Generate(FIB).Limit(Ten).ForEach(System. out::p rintln);
Operation of the java8-stream