Java8 API Added a new abstract flow Stream, It can perform very complex lookups , Operations such as filtering and mapping data . use Stream API
Operate on set data , It's similar to using SQL Database query executed .Stream Is to treat the set data as a stream , The flow is transmitted in the pipeline , We can sort, aggregate and other operations in the pipeline .
In the process of writing code at ordinary times , When it comes to collection operations ,Stream API It can greatly improve our productivity , Let's write efficiency , clean , Concise code .Stream
API There are many operations available , Here are some common methods .
Basics Stream API
forEach
forEach Is every element in the iterative flow .
1
2
3
4
5
6
7
8@Test
public void testForeach() {
Random random = new Random();
List list= new ArrayList<>();
//random.ints(-100,100).limit(10).forEach(System.out::println);
random.ints(-100,100).limit(10).forEach(t->list.add(t));
System.out.println(list);
}
The above is used forEach Iterative output each -100 to 100 Random value of , output 10 individual , You can also iterate into a new one List aggregate .
map
map Operate on each element in the stream , Returns a new stream
1
2
3
4
5
6
7
8
9
10
11
12@Test
public void testMap(){
// Just convection operation does not change the original List Data in
//Stream fruit=Stream.of("apple","orange","banner","pear");
List fruit = Arrays.asList("apple","orange","banner","pear");
fruit.stream().sorted().map(String::toUpperCase).forEach(System.out::println);
System.out.println(fruit);
// Returns a new stream
List newfruit =
fruit.stream().map(v->v.toUpperCase()).collect(Collectors.toList());
System.out.println(newfruit);
}
The above is to capitalize each element , Or output or return to a new collection
filter
filter Method is used to filter out elements by setting conditions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19/**
* Long Array selection is not Null And greater than 0 Value of
* @param t
* @return
*/
public static Long[] removeNullAndZero(Long[] t) {
List list = Arrays.asList(t);
return list.stream().filter(v->v!=null && v>0).toArray(Long[] :: new);
}
/**
* selection String array Not for Null Value of
* @param t
* @return
*/
public static String[] removeNullAndZero(String[] t) {
List list = Arrays.asList(t);
return list.stream().filter(v->v!=null).toArray(String[] :: new);
}
filter Null Or greater than 0 Element of
1
2
3
4
5
6@Test
public void testFilter() {
List intList = Arrays.asList(8,2,4,1,8,3,10,6,6,15);
List
newIntList=intList.stream().filter(i->i>5).sorted().distinct().collect(Collectors.toList());
System.out.println(newIntList);
}
The above filter is greater than 5 Value of , And sort , Take the unique number and output it to the new set .
parallelStream
parallelStream Is an alternative to stream parallel processing , Compare Stream Multi pipeline operation . It is based on ForkJoinPool Executing concurrent tasks .
characteristic
use parallelStream It can write concurrent code concisely and efficiently .
parallelStream Parallel execution is out of order .
parallelStream Provides a simpler implementation of concurrent execution , But it doesn't mean higher performance , It is used according to specific application scenarios . If cpu Resource shortage parallelStream No performance improvement ; If there is frequent thread switching, it will reduce performance .
It is better to be state independent between tasks , because parallelStream The default is non thread safe , Uncertainty of possible results .
Github On the right Parallel Enhanced , If you are interested, you can click to visit .
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15@Test
public void testParallel() {
Random random = new Random();
List list= new ArrayList<>();
random.ints(-10000,10000).limit(10000).forEach(t->list.add(t));
long start = System.currentTimeMillis();
list.stream().filter(e -> e > 1000 && e< 2000).collect(Collectors.toList());
System.out.println("stream : " + (System.currentTimeMillis() - start) + "ms");
start = System.currentTimeMillis();
list.parallelStream().filter(e -> e > 1000 && e <
2000).collect(Collectors.toList());
System.out.println("parallelStream : " + (System.currentTimeMillis() - start)
+ "ms");
}
Test concurrent processing speed , The above code tests this , test result parallelStream The speed is a little faster .
Count
Stream API It also provides simple statistical operations .
1
2
3
4
5
6
7
8
9
10
11@Test
public void testCount() {
List numList = Arrays.asList(6, 2, 4, 3, 7, 3, 5, 9);
DoubleSummaryStatistics stats = numList.stream().mapToDouble((x) ->
x).summaryStatistics();
System.out.println(" Total number : " + stats.getCount());
System.out.println(" Maximum number of in the list : " + stats.getMax());
System.out.println(" Minimum number in the list : " + stats.getMin());
System.out.println(" Sum of all numbers : " + stats.getSum());
System.out.println(" average : " + stats.getAverage());
}
Simple statistical function .
practical application
I will operate on collections in actual projects , use Stream API Can help me solve the problem concisely . The following is my actual use scenario .
Object class 1
2
3
4
5
6
7
8
9
10
11
12
13
14import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Person {
private String name;
private Integer gender;
private int age;
private double height;
}
Usage scenario
Construction data 1
2
3
4
5
6
7
8
9
10
11
12static List createPeople(){
List people=new ArrayList();
Person person=new Person(" Zhang San ",0,30,2.8);
people.add(person);
person=new Person(" Li Si ",0,32,1.6);
people.add(person);
person=new Person(" Wang Wu ",1,32,2.0);
people.add(person);
person=new Person(" Wang Wu ",1,33,1.6);
people.add(person);
return people;
}
Connect a property
Parallel display required , use , Connect a property
1
2
3
4
5
6
7
8@Test
public void CollectionStreamJoin(){
List people=createPeople();
Stream stream=people.stream();
// Take out the object's name value , Combined use , connect
String names = stream.map(v->v.getName()).collect(Collectors.joining(","));
System.out.println(names);
}
Get the unique value of an attribute
According to an attribute value , Delete selected object . Keep only unique attribute values
1
2
3
4
5
6
7
8
9@Test
public void distinctList() {
List people=createPeople();
List distinctlist = people.stream()
.collect(Collectors.collectingAndThen(
Collectors.toCollection(() -> new
TreeSet<>(Comparator.comparing(Person::getName))),
ArrayList::new));
System.out.println(distinctlist);
}
Multi attribute sorting
Multiple attributes are required to sort
1
2
3
4
5
6@Test
public void sortField() {
List people=createPeople();
people.sort(Comparator.comparing(Person::getAge).reversed().thenComparing(Person::getHeight));
System.out.println(JSON.toJSONString(people));
}
Sort after grouping
The object list is first grouped by a field , And sort according to the size of another field , Take the first object
1
2
3
4
5
6
7
8
9
10
11@Test
public void getOnlyOneByField() {
List people=createPeople();
Map map =new HashMap<>();
map = people.parallelStream()
.collect(Collectors.groupingBy(Person::getName,
Collectors.collectingAndThen(
Collectors.reducing((c1, c2) -> c1.getAge()>c2.getAge()?c1:c2),
Optional::get)));
System.out.println(map);
}
summary
use Stream
API The set of operations can make the code more concise , raise productivity . I am writing Stream When operating , Thinking is like writing SQL Similar statement , Include grouping , polymerization , Filtering and other operations , Those who encounter difficulties can learn from their thinking .
Technology
Daily Recommendation