1. Simple use
Last time, we talked about the new API stream of JAVA 8. If we have such a need, we need to pick out the name of the top three calorie dishes with less than 1000 calories in the recipe.
If we use the traditional way of writing JAVA 7, we should write as follows:
public List<String> findDish(List<Dish> menu){ List<Dish> lowCaloricDishes = new ArrayList<>(); for (Dish dish : lowCaloricDishes) { if(dish.getCalories() < 1000 ){ lowCaloricDishes.add(dish); } } Collections.sort(lowCaloricDishes, new Comparator<Dish>() { @Override public int compare(Dish o1, Dish o2) { return Integer.compare(o1.getCalories(),o2.getCalories()); } }); List<Dish> result = lowCaloricDishes.subList(0,3); List<String> resultName = new ArrayList<>(); for (Dish dish : result) { resultName.add(dish.getName()); } return resultName; }
From the example above, we can see that we use a lot of intermediate variables to store mediation results, low Caloric Dishes, result, resultName. It's rather tedious. If we use JAVA 8 streaming to implement the code as follows:
public List<String> findDishWithSteam(List<Dish> menu){ List<String> resultName = menu.stream() .filter(dish -> dish.getCalories()<1000) .sorted(Comparator.comparing(Dish::getCalories)) .limit(3) .map(Dish::getName) .collect(Collectors.toList()); return resultName; }
If we convert steam() to parallelStream(), the whole operation becomes parallel. The code is so elegant that I can't wait to use JAVA 8, considering how many collections we deal with every day.
2. Definition of flow
What is flow? The definition given in the book is "sequence of elements generated from sources that support data processing operations".
- Element sequences, like collections, can be understood as a bunch of ordered values. But collections focus on data, while streams focus on computation.
- The source stream uses a source that provides data. For example, in menu.stream(), meun is the source of this stream.
- The data processing function of data processing operation flow is similar. The operation of database also supports the operation in functional programming.
Let's look at some of the ways that interfaces java.util.stream.Stream have:
We can see that the method we used in the previous example, filter(), sorted(), limit(), map(), also has a stream Stream return value, that is to say, we can string all the operations together. This is a characteristic pipeline of flow.
Another feature is internal iteration. Unlike set iteration, flow iteration is not explicit iteration.
3. Basic operation of flow
1. Screening and slicing
-
Screening filter()
filter() accepts a function that returns boolean type.
For example:filter(dish -> dish.getCalories()<1000)
-
De-distinct()
The method of de-duplication can be analogous to distinct in SQL statements.
-
Truncate limit()
Similar to limit in SQL, accept a Long value. Returns the first n elements in the stream.
-
skip()
Skip the first n elements. Well understood
2. Mapping
-
map()
The application function of each element in map convection can be understood as transforming an element into another element.
.map(Dish::getName)
-
flatmap()
The flatmap method is to replace each element in the stream with another stream and merge it into one stream.
List<List<String>> lists = new ArrayList<>();
lists.add(Arrays.asList("apple", "click"));
lists.add(Arrays.asList("boss", "dig", "qq", "vivo"));
lists.add(Arrays.asList("c#", "biezhi"));
```
Find out all elements larger than two characters:
```java
lists.stream()
.flatMap(Collection::stream)
.filter(str -> str.length() > 2)
.count();
```
3. Find matches
match,anyMatch,allMatch,noneMatch
All of the above methods return a boolean type.
boolean hasLowCalories = mune.stream().anyMatch(dish -> dish.getCalories()<1000)
4. Reduction
reduce(T,BinaryOperator<T>)
The reduce operation combines each element repeatedly until the flow is reduced to a value. Among them:
- T refers to the initial value.
-
BinaryOperator < T> combines two elements to obtain an element, for example:
Lamdba: (a,b)-> a + b.
So given a List < Integer > compute and sum all int s:
int sum = list.stream().reduce(0,(a,b)-> a + b);
Or:
int sum = list.stream().reduce(0,Integer::sum);
5. Data collection
After an operation, we need to collect the data. You need to use the collect() method.
Map<String, Integer> map = meun.stream() .collect(Collectors.toMap(Dish::getName, Dish::getCalories));