Simple collection traversal
foreach traversal
import java.util.ArrayList; import java.util.List; /** * @author rx * @date 2022/6/1 17:18 */ public class Demo1Foreach { public static void main(String[] args) { List<String>list=new ArrayList<>(); list.add("w2"); list.add("zh3"); list.add("l4"); list.add("lao6"); list.add("tomas"); for (String s:list){ System.out.println(s); } } }
Iterator traversal
import java.util.ArrayList; import java.util.Iterator; import java.util.List; /** * @author rx * @date 2022/6/1 17:18 */ public class Demo1Foreach { public static void main(String[] args) { List<String>list=new ArrayList<>(); list.add("w2"); list.add("zh3"); list.add("l4"); list.add("lao6"); list.add("tomas"); Iterator<String> iterator = list.iterator(); while (iterator.hasNext()){ System.out.println(iterator.next()+"\t"); } } }
There are the following scenarios
- Filter set A into subset B according to condition 1;
- Then it is filtered into subset C according to condition 2.
Use Java8 first
import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.stream.Collectors; /** * @author rx * @date 2022/6/1 17:18 */ public class Demo1Foreach { public static void main(String[] args) { List<String>list=new ArrayList<>(); List<String>listA=new ArrayList<>(); List<String>listB=new ArrayList<>(); list.add("w2"); list.add("zh3"); list.add("l4"); list.add("lao6"); list.add("tomas"); for (String s:list){ if (s.startsWith("l")){ listA.add(s); } } for (String s:listA){ if (s.length()==4){ listB.add(s); } } for (String s:listB){ System.out.println(s); } } }
Better writing of Stream() stream
1. scenario 1: filtering
1.1 data filtering based on filter()
This method will receive a function that returns boolean as a parameter and eventually return a stream that includes all qualified elements.
import jdk.nashorn.internal.ir.IfNode; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.stream.Collectors; /** * @author rx * @date 2022/6/1 17:18 */ public class StreamDemo1 { public static void main(String[] args) { List<String>list=new ArrayList<>(); List<String>listA=new ArrayList<>(); List<String>listB=new ArrayList<>(); list.add("w2"); list.add("zh3"); list.add("l4"); list.add("lao6"); list.add("tomas"); list.stream().filter( name->name.startsWith("l") ).filter( name->name.length()==4 ).forEach(name-> System.out.println(name)); } }
import jdk.nashorn.internal.ir.IfNode; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; /** * @author rx * @date 2022/6/1 17:18 */ public class StreamDemo2 { public static void main(String[] args) { List<Student>students=new ArrayList<>(); students.add(new Student("wang2",5,"f")); students.add(new Student("zh3",3,"f")); students.add(new Student("li4",5,"f")); students.stream().filter(student -> student.getName().length() == 3 && student.getAge() < 5 ).forEach(System.out::println); } } class Student { public Student(String name, int age, String gender) { this.name = name; this.age = age; this.gender = gender; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + ", gender='" + gender + '\'' + '}'; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } private String name; private int age; private String gender; }
1.2 data De duplication based on distinct
import java.util.Arrays; import java.util.List; /** * @author rx * @date 2022/6/3 10:04 */ public class StreamDemo3 { public static void main(String[] args) { List<Integer> numbers = Arrays.asList(1, 2, 4, 5, 3, 2, 1, 3, 4, 5, 6, 5, 7, 8); numbers.stream().distinct().forEach(System.out::println); } }
Within distinct(), the data in the stream is de duplicated based on the LinkedHashSet, and finally a new stream is returned.
2. slicing
2.1 data interception based on limit()
import java.util.Arrays; import java.util.List; /** * @author rx * @date 2022/6/3 10:04 */ public class StreamDemo5 { public static void main(String[] args) { List<Integer> numbers = Arrays.asList(1, 2, 4, 5, 3, 2, 1, 3, 4, 5, 6, 5, 7, 8); numbers.stream().limit(3).forEach(System.out::println); } }
2.2 data skipping based on skip()
import java.util.Arrays; import java.util.List; /** * @author rx * @date 2022/6/3 10:04 */ public class StreamDemo6 { public static void main(String[] args) { List<Integer> numbers = Arrays.asList(1, 2, 4, 5, 3, 2, 1, 3, 4, 5, 6, 5, 7, 8); numbers.stream().skip(3).forEach(System.out::println); } }
3. mapping
A similar method, map(), is provided in the Stream API. It takes a function as a method parameter, which is applied to each element in the collection and finally mapped to a new element. Case: get the names of all students and form a new set.
public class StreamDemo7 { public static void main(String[] args) { List<Student>students=new ArrayList<>(); students.add(new Student("wang2",5,"f")); students.add(new Student("zh3",3,"f")); students.add(new Student("li4",5,"f")); List<String> stringList = students.stream().map(student -> student.getName()).collect(Collectors.toList()); stringList.stream().forEach(System.out::println); } }
4. Match
boolean anyMatch(), boolean allMatch(), and boolean noneMatch() methods.
import jdk.nashorn.internal.ir.IfNode; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; /** * @author rx * @date 2022/6/1 17:18 */ public class StreamDemo8 { public static void main(String[] args) { List<Student>students=new ArrayList<>(); students.add(new Student("wang2",5,"f")); students.add(new Student("zh3",3,"f")); students.add(new Student("li4",5,"f")); if (students.stream().allMatch(student -> student.getAge()<5)){ System.out.println("have "); }else { System.out.println("don't"); } } }
5. find
For collection operations, it is sometimes necessary to find qualified elements in the collection. Relevant API s are also provided in Stream, and "ndAny() and" ndFirst() can be used in combination with other flow operations. "Nandany" is used to get a random element in the Stream, and "ndFirst" is used to get the first element in the Stream. As for some special customization requirements, they need to be realized by themselves.
5.1 find elements based on "endany()"
Case: "nandany" is used to obtain a random element in the flow, and use a short circuit to end immediately when finding the result
public class StreamDemo9 { public static void main(String[] args) { List<Student>students=new ArrayList<>(); students.add(new Student("wang2",5,"f")); students.add(new Student("zh3",3,"f")); students.add(new Student("li4",5,"f")); Optional<Student> optionalStudent = students.stream().filter(student -> student.getName().length() == 3).findAny(); System.out.println(optionalStudent.toString()); } }
5.2 find elements based on "ndFirst()"
The principle of "ndFirst" is similar to that of findAny, except that it returns the first element no matter whether it is a serial stream or a parallel stream
6. Reduction
Up to now, for the terminal operation of the stream, we have returned boolean, Optional and List. However, in collection operations, we often involve operations such as statistical calculation of elements, such as summation, large value and small value, so as to return different data results.
6.1 cumulative sum based on reduce()
import java.util.Arrays; import java.util.List; /** * @author rx * @date 2022/6/3 13:34 */ public class StreamDemo10 { public static void main(String[] args) { List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); Integer reduce = list.stream().reduce(0, (x1, x2) -> x1 + x2); System.out.println(reduce); } }
In the above code, the first parameter in reduce is declared as the initial value, and the second parameter receives a lambda expression representing the two elements in the current flow. It will add each element repeatedly until the flow is reduced to a final result
import java.util.Arrays; import java.util.List; import java.util.Optional; /** * @author rx * @date 2022/6/3 13:34 */ public class StreamDemo11 { public static void main(String[] args) { List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); Optional<Integer> reduce = list.stream().reduce(Integer::sum); if (reduce.isPresent()){ System.out.println(reduce); }else System.out.println("data is error"); } }
6.2 get the maximum and minimum values in the stream
public class StreamDemo12 { public static void main(String[] args) { List<Integer> integers = Arrays.asList(1, 2, 3, 4, 4, 5, 5, 6, 7, 8, 2, 2, 2, 2); /** * Get the maximum value in the collection */ //Method 1 Optional<Integer> max1 = integers.stream().reduce(Integer::max); if(max1.isPresent()){ System.out.println(max1); } //Method II Optional<Integer> max2 = integers.stream().max(Integer::compareTo); if(max2.isPresent()){ System.out.println(max2); } /** * Get the minimum value in the collection */ //Method 1 Optional<Integer> min1 = integers.stream().reduce(Integer::min); if(min1.isPresent()){ System.out.println(min1); } //Method II Optional<Integer> min2 = integers.stream().min(Integer::compareTo); if(min2.isPresent()){ System.out.println(min2); } } }
7. Collector
By using the collector, the code can be simplified and reused more conveniently. Its internal core is to complete more complex calculation conversion through Collectors, so as to obtain the final results. In addition, Collectors provide many common static methods, which can be directly used. For example: toList.
import jdk.nashorn.internal.ir.IfNode; import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; /** * @author rx * @date 2022/6/1 17:18 */ public class StreamDemo13 { public static void main(String[] args) { List<Student> students = new ArrayList<>(); students.add(new Student("wang2", 5, "f")); students.add(new Student("zh3", 3, "f")); students.add(new Student("yx", 88, "f")); //Calculate the number, method 1 Long collect = students.stream().collect(Collectors.counting()); System.out.println(collect); //Calculate the number, method 2 long count = students.stream().count(); System.out.println(count); //Find the maximum value through maxBy, method 1 Optional<Student> optional1 = students.stream().collect(Collectors.maxBy(Comparator.comparing(student -> student.getAge()))); if (optional1.isPresent()) { System.out.println(optional1); } //Find the maximum value through maxBy, method 2 Optional<Student> max = students.stream().max(Comparator.comparing(Student::getAge)); if (max.isPresent()) { System.out.println(max); } //Summarize data through summingInt() Integer collect1 = students.stream().collect(Collectors.summingInt(Student::getAge)); System.out.println(collect1); //Get the average value through averagingInt() Double collect3 = students.stream().collect(Collectors.averagingInt(student -> student.getAge())); System.out.println(collect3); //Data splicing through joining method String collect2 = students.stream().map(Student::getName).collect(Collectors.joining()); System.out.println(collect2); //Return of complex results IntSummaryStatistics collect4 = students.stream().collect(Collectors.summarizingInt(Student::getAge)); collect4.getSum(); collect4.getMax(); collect4.getCount(); collect4.getAverage(); collect4.getMin(); } }
8. Grouping
In database operations, query results are often grouped by group by. At the same time, this kind of operation is often involved in daily development, such as grouping student sets by gender. If you need to write a lot of code through ordinary coding and the readability is not good.
To solve this problem, java8 also provides a way to simplify writing. Through Collectors. groupingBy().
public class StreamDemo14 { public static void main(String[] args) { List<Student> students = new ArrayList<>(); students.add(new Student("wang2", 5, "m")); students.add(new Student("zh3", 3, "f")); students.add(new Student("yx", 88, "m")); students.add(new Student("sd", 88, "f")); students.add(new Student("cd", 88, "m")); Map<String, List<Student>> collect = students.stream().collect(Collectors.groupingBy(Student::getGender)); System.out.println(collect); //Results: {f=[Student{name='zh3', age=3, gender='f'}, Student{name='sd', age=88, gender='f'}], m=[Student{name='wang2', age=5, gender='m'}, Student{name='yx', age=88, gender='m'}, Student{name='cd', age=88, gender='m'}]} } }
8.1 multi level grouping
public class StreamDemo15 { public static void main(String[] args) { List<Student> students = new ArrayList<>(); students.add(new Student("wang2", 5, "m")); students.add(new Student("zh3", 3, "f")); students.add(new Student("yx", 88, "m")); students.add(new Student("sd", 88, "f")); students.add(new Student("cd", 88, "m")); Map<String, Map<String, List<Student>>> collect = students.stream().collect(Collectors.groupingBy(Student::getGender, Collectors.groupingBy(Student::getGender))); System.out.println(collect); //Results: {f={f=[Student{name='zh3', age=3, gender='f'}, Student{name='sd', age=88, gender='f'}]}, m={m=[Student{name='wang2', age=5, gender='m'}, Student{name='yx', age=88, gender='m'}, Student{name='cd', age=88, gender='m'}]} } }