When we do projects, we often need to integrate and filter the data, and judge after using the for loop every time. I believe you must be tired. Now the Lamda expression newly exited by Java 8 and Steam API can perfectly process the data and complete the function of shuttling between the data.
Stream means stream, which is slightly different from IO stream. We get the desired data by pipelining the data stream.
Create stream from Stream API
There are many ways to create a stream, including through the instance method. stream() of the collection, through the static method Arrays.stream() of the array tool class, through the static method Stream.of() of the stream class, and through Stream.iterate(); The last one is to create an infinite flow, that is, it runs all the time without ending.
Collection instance method creation
Creating a flow through the collection instance method is the form we generally use.
// 1. The stream can be obtained through the stream() or parallel stream() provided by the Collection series Collection List<String> list = new ArrayList<>(); Stream<String> stream = list.stream();
Create a stream using static methods of the array utility class
// 2. The array stream can be obtained through the static method stream() in Arrays Employee[] emps = new Employee[10]; Stream<Employee> stream1 = Arrays.stream(emps);
Stream static method of()
// 3. Through the static method in Stream () Stream<String> stream2 = Stream.of("aa", "bb", "vv");
Stream static methods iterate() and generate()
Stream's iterate() creates an infinite stream. What is an infinite stream? It means that the operation will never stop without terminating.
// 4. Create an infinite stream // iteration Stream<Integer> stream3 = Stream.iterate(0, (x) -> x + 2); stream3.limit(10).forEach(System.out::println); // generate Stream.generate(() -> (Math.random())) .limit(5) .forEach(System.out::println);
Intermediate operations of Stream API
There are many intermediate operations in Stream API, such as filtering, specification, mapping, sorting, etc.
The intermediate operation of Stream has a distinct property: when the terminal operation is not executed, the intermediate operation is not executed; When the terminal operation is performed, the terminal operation is performed in the form of pipeline.
Screening and slicing
The Stream API provides methods for filtering and slicing data streams, which are:
filter -- receives Lamda and excludes elements from the stream.
limit -- truncate the stream so that its elements do not exceed the given number.
skip(n) -- skip elements and rush back to a stream that throws away the first n elements. If there are less than n elements in the stream, an empty stream is returned. Complementary to limit(n).
distinct -- remove the duplicate, and take out the duplicate elements through hanshcode() and equals() of the elements generated by the stream.
@Test public void test5(){ emps.stream() .distinct() .forEach(System.out::println); } @Test public void test4() { emps.stream() .filter((e) -> e.getSalary()<5000) .skip(2) .forEach(System.out::println); } @Test public void test3() { emps.stream() .filter((e) -> { System.out.println("Short circuit!"); return e.getSalary() < 5000; }) .limit(2) .forEach(System.out::println); } // Internal iteration: the iteration operation is completed by Stream API @Test public void test1() { // Intermediate operation: no processing will be performed Stream<Employee> s = emps.stream() .filter((e) -> { System.out.println("Stream API Intermediate operation of"); return e.getAge() > 35; }); // Terminate operation: all contents are executed at once, i.e. "lazy evaluation" s.forEach(System.out::println); }
mapping
In the Strame API, there are two APIs that provide mapping functions: map and flatMap.
map: take a function as a parameter, and each element in the stream will execute this function and reorganize the stream in the form of the return value of the function.
flatMap: take a function as a parameter, take each value in the stream as another stream, and then connect all streams into one stream.
The difference between map and flatMap is that no matter what type of value returned by the accepted function, flapMap arranges each element into a stream, and finally connects all streams into a stream, while map just puts the returned value into the stream.
For example, when the received function returns a stream, the map is finally combined into a nested stream in the stream, while the flapMap only returns the stream in which all elements are strung together.
@Test public void test6() { List<String> list = Arrays.asList("aaa", "bb", "as", "ee"); list.stream() .map((str) -> str.toUpperCase()) .forEach(System.out::println); System.out.println("======================="); emps.stream() .map(Employee::getName) .forEach(System.out::println); System.out.println("======================="); Stream<Stream<Character>> stream = list.stream() .map(TestStreamAPI2::filterCharacter); stream.forEach((sm) -> { sm.forEach(System.out::println); }); System.out.println("======================="); list.stream() .flatMap(TestStreamAPI2::filterCharacter) .forEach(System.out::println); }
sort
There is only one sorting method provided by Stream API, sorted(), but it has two methods: with and without parameters;
sorted() natural sort
sorted(Comparator com) -- customized sorting
@Test public void test7() { List<String> list = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee"); list.stream() .sorted() .forEach(System.out::println); System.out.println("================="); emps.stream() .sorted((x,y) -> { if (x.getAge().equals(y.getAge())){ return x.getName().compareTo(y.getName()); }else { return x.getAge().compareTo(y.getAge()); } }).forEach(System.out::println); }
Terminate operation
Stream provides a variety of termination API s, which can perfectly cooperate with intermediate operations to process data.
Find and match
allMatch -- check to see if all elements match
anyMatch -- check to see if at least one element matches
noneMatch -- check if all elements are not matched
findFirst -- returns the first element
findAny -- returns all elements in the current stream
count -- returns the total number of elements in the stream
max -- returns the maximum value in the stream
min -- minimum value in return flow
@Test public void test2() { long count = emps.stream() .count(); System.out.println(count); System.out.println("============================"); Optional<Employee> max = emps.stream() .max((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())); System.out.println(max.get()); System.out.println("============================"); // Optional<Employee> min = emps.stream() // .min((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())); // System.out.println(min.get().getSalary()); Optional<Double> min = emps.stream() .map(Employee::getSalary) .min(Double::compareTo); System.out.println(min.get()); } @Test public void test1() { boolean b = emps.stream() .allMatch((e) -> e.getStatus().equals(Employee.Status.BUSY)); System.out.println(b); System.out.println("==========================="); boolean b1 = emps.stream() .anyMatch((e) -> e.getStatus().equals(Employee.Status.BUSY)); System.out.println(b1); System.out.println("==========================="); boolean b2 = emps.stream() .noneMatch((e) -> e.getStatus().equals(Employee.Status.BUSY)); System.out.println(b2); System.out.println("==========================="); Optional<Employee> op = emps.stream() .sorted((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())) .findFirst(); System.out.println(op.get()); System.out.println("==========================="); Optional<Employee> any = emps.stream() .filter((e) -> e.getStatus().equals(Employee.Status.FREE)) .findAny(); System.out.println(any.get()); }
reduction
Reduce (t identity, binary operator) / reduce (binary operator) - you can combine the elements in the stream repeatedly to get a value.
The essence is recursion.
@Test public void test3() { List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); // Find the number in the array. 0 is the initial value Integer sum = list.stream() .reduce(0, (x, y) -> x + y); System.out.println(sum); System.out.println("================================="); Optional<Double> op = emps.stream() .map(Employee::getSalary) .reduce(Double::sum); System.out.println(op.get()); }
collect
Because the collection operation is the most common in work, the collection operation method is very common.
collect -- convert the Stream to another form. Accept the implementation of a Collector interface, which is used to summarize the elements in the Stream.
@Test public void test10() { String str = emps.stream() .map(Employee::getName) .collect(Collectors.joining(",")); System.out.println(str); } @Test public void test9() { DoubleSummaryStatistics dss = emps.stream() .collect(Collectors.summarizingDouble(Employee::getSalary)); System.out.println(dss.getMax()); } // partition @Test public void test8() { Map<Boolean, List<Employee>> map = emps.stream() .collect(Collectors.partitioningBy((e) -> e.getSalary() > 8000)); System.out.println(map); } // Multilevel grouping @Test public void test7() { Map<Employee.Status, Map<String, List<Employee>>> mapMap = emps.stream() .collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy((e) -> { if (e.getAge() < 30) { return "youth"; } else if (e.getAge() <= 50) { return "middle age"; } else { return "old age"; } }))); System.out.println(mapMap); } // grouping @Test public void test6() { Map<Employee.Status, List<Employee>> map = emps.stream() .collect(Collectors.groupingBy(Employee::getStatus)); System.out.println(map); } @Test public void test5() { // total Long count = emps.stream() .collect(Collectors.counting()); System.out.println(count); // average value Double avage = emps.stream() .collect(Collectors.averagingDouble(Employee::getSalary)); System.out.println(avage); // the sum Double sum = emps.stream() .collect(Collectors.summingDouble(Employee::getSalary)); System.out.println(sum); // Maximum Optional<Double> max = emps.stream() .map(Employee::getSalary) .collect(Collectors.maxBy((e1, e2) -> Double.compare(e1, e2))); System.out.println(max.get()); // minimum value Optional<Double> min = emps.stream() .map(Employee::getSalary) .collect(Collectors.minBy(Double::compareTo)); System.out.println(min); } @Test public void test4() { List<String> list = emps.stream() .map(Employee::getName) .collect(Collectors.toList()); list.forEach(System.out::println); System.out.println(list.toString()); HashSet<String> collect = emps.stream() .map(Employee::getName) .collect(Collectors.toCollection(HashSet::new)); collect.forEach(System.out::println); }