1. Functional interface
1.1 Functional Interface Overview [Understanding]
-
concept
An interface with and only one abstract method
-
How to detect whether an interface is a functional interface
@FunctionalInterface
Place it above the interface definition: If the interface is a functional interface, the compilation passes; if not, the compilation fails.
-
Matters needing attention
When we define functional interfaces ourselves, @Functional Interface is optional. Even if I don't write this annotation, it's still a functional interface as long as the conditions for the definition of functional interfaces are satisfied. However, it is suggested that the commentary be added.
1.2 Functional Interface as the Parameter of Method [Application]
-
Requirement description
Define a class (RunnableDemo) that provides two methods in the class
One way is that the startThread (Runnable) method parameter Runnable is a functional interface.
One way is to call the startThread method in the main method
-
Code demonstration
public class RunnableDemo { public static void main(String[] args) { //Call the startThread method in the main method //Ways of anonymous inner classes startThread(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName() + "Thread started"); } }); //Lambda mode startThread(() -> System.out.println(Thread.currentThread().getName() + "Thread started")); } private static void startThread(Runnable r) { new Thread(r).start(); } }
1.3 Functional Interface as Return Value of Method [Application]
-
Requirement description
Define a class (Comparator Demo) that provides two methods in the class
One way is that the Comparator getComparator() method return value Comparator is a functional interface
One way is to call the getComparator method in the main method
-
Code demonstration
public class ComparatorDemo { public static void main(String[] args) { //Define collections, store string elements ArrayList<String> array = new ArrayList<String>(); array.add("cccc"); array.add("aa"); array.add("b"); array.add("ddd"); System.out.println("Before sorting:" + array); Collections.sort(array, getComparator()); System.out.println("After sorting:" + array); } private static Comparator<String> getComparator() { //How to Implement Anonymous Internal Classes // return new Comparator<String>() { // @Override // public int compare(String s1, String s2) { // return s1.length()-s2.length(); // } // }; //Implementation of Lambda return (s1, s2) -> s1.length() - s2.length(); } }
1.4 Supplier for Common Functional Interfaces
-
Supplier interface
Supplier interfaces are also called production interfaces. If we specify the generic type of the interface, the get method in the interface will produce what kind of data for us to use.
-
common method
There is only one method without reference.
Method name Explain T get() Return a data according to some implementation logic (implemented by Lambda expressions) -
Code demonstration
public class SupplierDemo { public static void main(String[] args) { String s = getString(() -> "Lin Qingxia"); System.out.println(s); Integer i = getInteger(() -> 30); System.out.println(i); } //Define a method that returns an integer data private static Integer getInteger(Supplier<Integer> sup) { return sup.get(); } //Define a method that returns a string data private static String getString(Supplier<String> sup) { return sup.get(); } }
Maximum Acquisition of 1.5 Supplier Interface Exercise [Application]
-
Case requirements
Define a class (Supplier Test) that provides two methods in the class
One way is to use int getMax(Supplier sup) to return the maximum value in an int array
One way is to call the getMax method in the main method
-
Sample code
public class SupplierTest { public static void main(String[] args) { //Define an int array int[] arr = {19, 50, 28, 37, 46}; int maxValue = getMax(()-> { int max = arr[0]; for(int i=1; i<arr.length; i++) { if(arr[i] > max) { max = arr[i]; } } return max; }); System.out.println(maxValue); } //Returns the maximum value in an int array private static int getMax(Supplier<Integer> sup) { return sup.get(); } }
1.6 Consumer [Application] of Common Functional Interfaces
-
Consumer interface
Consumer interface, also known as consumer interface, consumes data types specified by generics
-
common method
Consumer: Contains two methods
Method name Explain void accept(T t) Perform this operation on a given parameter default Consumer andThen(Consumer after) Returns a composite Constumer, performs this operation in turn, and then performs the after operation. -
Code demonstration
public class ConsumerDemo { public static void main(String[] args) { //Operation I operatorString("Lin Qingxia", s -> System.out.println(s)); //Operation II operatorString("Lin Qingxia", s -> System.out.println(new StringBuilder(s).reverse().toString())); System.out.println("--------"); //Input two operations are done using andThen operatorString("Lin Qingxia", s -> System.out.println(s), s -> System.out.println(new StringBuilder(s).reverse().toString())); } //Define a method to consume the same string data twice in different ways private static void operatorString(String name, Consumer<String> con1, Consumer<String> con2) { // con1.accept(name); // con2.accept(name); con1.andThen(con2).accept(name); } //Define a method to consume a string data private static void operatorString(String name, Consumer<String> con) { con.accept(name); } }
1.7 Print Information as Required for Consumer Interface Exercises [Application]
-
Case requirements
String[] strArray = {"Lin Qingxia, 30", "Zhang Manyu, 35", "Wang Zuxian, 33"};
There are many pieces of information in the string array. Please print out the information in the format of "Name: XX, Age: XX".
Requirement:
Use the action of printing names as an example of Lambda for the first Consumer interface
Lambda example of the second Consumer interface with the action of printing age
Combine the two Consumer interfaces sequentially
-
Sample code
public class ConsumerTest { public static void main(String[] args) { String[] strArray = {"Lin Qingxia,30", "Zhang Manyu,35", "Wang Zuxian,33"}; printInfo(strArray, str -> System.out.print("Full name:" + str.split(",")[0]), str -> System.out.println(",Age:" + Integer.parseInt(str.split(",")[1]))); } private static void printInfo(String[] strArray, Consumer<String> con1, Consumer<String> con2) { for (String str : strArray) { con1.andThen(con2).accept(str); } } }
1.8 Predicate of Common Functional Interfaces
-
Predicate interface
Predicate interfaces are often used to determine whether parameters satisfy specified conditions
-
common method
Method name Explain boolean test(T t) Judgment of a given parameter (judgement logic is implemented by Lambda expression) returns a Boolean value default Predicate negate() Return a logical negation, corresponding to a logical non-negation default Predicate and(Predicate other) Return a combination judgement, corresponding to the short circuit and the ___________ default Predicate or(Predicate other) Returns a combination judgement, corresponding to a short circuit or -
Code demonstration
public class PredicateDemo01 { public static void main(String[] args) { boolean b1 = checkString("hello", s -> s.length() > 8); System.out.println(b1); boolean b2 = checkString("helloworld",s -> s.length() > 8); System.out.println(b2); } //Determine whether a given string meets the requirements private static boolean checkString(String s, Predicate<String> pre) { // return !pre.test(s); return pre.negate().test(s); } } public class PredicateDemo02 { public static void main(String[] args) { boolean b1 = checkString("hello", s -> s.length() > 8); System.out.println(b1); boolean b2 = checkString("helloworld", s -> s.length() > 8); System.out.println(b2); boolean b3 = checkString("hello",s -> s.length() > 8, s -> s.length() < 15); System.out.println(b3); boolean b4 = checkString("helloworld",s -> s.length() > 8, s -> s.length() < 15); System.out.println(b4); } //Two different judgment conditions are given for the same string. Finally, the result of the two judgments is taken as the final result of logic and operation. private static boolean checkString(String s, Predicate<String> pre1, Predicate<String> pre2) { return pre1.or(pre2).test(s); } //Determine whether a given string meets the requirements private static boolean checkString(String s, Predicate<String> pre) { return pre.test(s); } }
1.9 Predicate Interface Exercise Screening Satisfies Conditional Data [Application]
-
Exercise Description
-
String[] strArray = {"Lin Qingxia, 30", "Liuyan, 34", "Zhang Manyu, 35", "Mink Cicada, 31", "Wang Zuxian, 33"};
-
There are many pieces of information in the string array. Please filter the required strings into the set ArrayList through the assembly of the Predicate interface and traverse the set of ArrayList.
-
At the same time, the following requirements are met: the length of the name is longer than 2; the age is older than 33.
-
-
Analysis
-
There are two criteria, so you need to use two Predicate interfaces to judge the criteria.
-
Two conditions must be satisfied at the same time, so the and method can be used to connect the two judgment conditions.
-
-
Sample code
public class PredicateTest { public static void main(String[] args) { String[] strArray = {"Lin Qingxia,30", "Liu Yan,34", "Zhang Manyu,35", "army officer's hat ornaments,31", "Wang Zuxian,33"}; ArrayList<String> array = myFilter(strArray, s -> s.split(",")[0].length() > 2, s -> Integer.parseInt(s.split(",")[1]) > 33); for (String str : array) { System.out.println(str); } } //Screening qualified strings into the set ArrayList by assembling the Predicate interface private static ArrayList<String> myFilter(String[] strArray, Predicate<String> pre1, Predicate<String> pre2) { //Define a collection ArrayList<String> array = new ArrayList<String>(); //foreach for (String str : strArray) { if (pre1.and(pre2).test(str)) { array.add(str); } } return array; } }
Function [Application] of 1.10 Common Functional Interfaces
-
Function interface
Function < T, R > interfaces are usually used to process parameters, transform (processing logic is implemented by Lambda expressions), and then return a new value.
-
common method
Method name Explain R apply(T t) Applying this function to a given parameter default Function andThen(Function after) Returns a composite function, which is first applied to the input, and then to the result. -
Code demonstration
public class FunctionDemo { public static void main(String[] args) { //Operation I convert("100",s -> Integer.parseInt(s)); //Operation II convert(100,i -> String.valueOf(i + 566)); //Continuous execution of two operations using andThen convert("100", s -> Integer.parseInt(s), i -> String.valueOf(i + 566)); } //Define a method to convert a string to an int type and output it in the console private static void convert(String s, Function<String,Integer> fun) { // Integer i = fun.apply(s); int i = fun.apply(s); System.out.println(i); } //Define a method to add an integer to an int-type data and convert it to a string for console output private static void convert(int i, Function<Integer,String> fun) { String s = fun.apply(i); System.out.println(s); } //Define a method to convert a string to an int type, add an integer to the data of the int type, and convert it to a string output in the console. private static void convert(String s, Function<String,Integer> fun1, Function<Integer,String> fun2) { String ss = fun1.andThen(fun2).apply(s); System.out.println(ss); } }
1.11 Function Interface Exercises Operate Data According to Specific Requirements [Application]
-
Exercise Description
-
String s = Lin Qingxia, 30;
-
Please follow my instructions:
1: String truncation to the digital age section
2: Convert the previous step's age string to int-type data
3: Add the last step's int data to 70, and get an int result, which is output in the console.
-
Use Function Interface to Realize Function Splicing
-
-
Sample code
public class FunctionTest { public static void main(String[] args) { String s = "Lin Qingxia,30"; convert(s, ss -> ss.split(",")[1], Integer::parseInt, i -> i + 70); } private static void convert(String s, Function<String, String> fun1, Function<String, Integer> fun2, Function<Integer, Integer> fun3) { int i = fun1.andThen(fun2).andThen(fun3).apply(s); System.out.println(i); } }
2.Strem flow
2.1 Experience Stream Flow [Understanding]
-
Case requirements
Complete the creation and traversal of the collection as follows
- Create a collection that stores multiple string elements
- Store all elements in a collection that begin with "Zhang" into a new collection
- Store elements of length 3 in the set beginning with "Zhang" into a new set
- The set obtained by traversing the previous step
-
Sample code for raw mode
public class StreamDemo { public static void main(String[] args) { //Create a collection that stores multiple string elements ArrayList<String> list = new ArrayList<String>(); list.add("Lin Qingxia"); list.add("Zhang Manyu"); list.add("Wang Zuxian"); list.add("Liu Yan"); list.add("Aman Chang"); list.add("Zhang Wuji"); //Store all elements in a collection that begin with "Zhang" into a new collection ArrayList<String> zhangList = new ArrayList<String>(); for(String s : list) { if(s.startsWith("Zhang")) { zhangList.add(s); } } // System.out.println(zhangList); //Store elements of length 3 in the set beginning with "Zhang" into a new set ArrayList<String> threeList = new ArrayList<String>(); for(String s : zhangList) { if(s.length() == 3) { threeList.add(s); } } // System.out.println(threeList); //The set obtained by traversing the previous step for(String s : threeList) { System.out.println(s); } System.out.println("--------"); //Stream streams to improve // List. stream (). filter (s - > s. startsWith ("Zhang"). filter (s - > s. length () == 3). forEach (s - > System. out. println (s)); list.stream().filter(s -> s.startsWith("Zhang")).filter(s -> s.length() == 3).forEach(System.out::println); } }
-
Using Stream Stream Stream Stream Sample Code
public class StreamDemo { public static void main(String[] args) { //Create a collection that stores multiple string elements ArrayList<String> list = new ArrayList<String>(); list.add("Lin Qingxia"); list.add("Zhang Manyu"); list.add("Wang Zuxian"); list.add("Liu Yan"); list.add("Aman Chang"); list.add("Zhang Wuji"); //Stream streams to improve list.stream().filter(s -> s.startsWith("Zhang")).filter(s -> s.length() == 3).forEach(System.out::println); } }
-
Stream Stream Stream Stream Stream Stream Stream Stream Stream Stream Stream Stream Stream Stream Stream Stream Stream Stream Stream Stream Stream Stream Stream Stream Stream Stream Stream Stream
-
Read the literal meaning of the code directly and display the semantics of irrelevant logic perfectly: get stream, filter name sheet, filter length is 3, print one by one.
-
Stream Stream streams introduce a true functional programming style into Java
-
2.2 Stream Stream Flow Generation
-
Stream Stream Stream Stream
[External Link Picture Transfer Failure (img-BPvMmxB-1565867349540) (img Stream Stream Stream Stream Thought. jpg)]
-
How Stream streams are generated
-
Collection System Set
Using the default method stream() to generate the stream, default Stream stream()
-
Map System Set
Convert Map into Set Set Set Set Set Set Set Set Set Set Set Set Set Set Set Set Set Set Set Set Set Set Set Set Set Set Set Set Set
-
array
The static method of(T... values) generated Stream
-
-
Code demonstration
public class StreamDemo { public static void main(String[] args) { //Collection collections can use the default stream() method to generate streams List<String> list = new ArrayList<String>(); Stream<String> listStream = list.stream(); Set<String> set = new HashSet<String>(); Stream<String> setStream = set.stream(); //Indirect Generative Flow of Sets in Map System Map<String,Integer> map = new HashMap<String, Integer>(); Stream<String> keyStream = map.keySet().stream(); Stream<Integer> valueStream = map.values().stream(); Stream<Map.Entry<String, Integer>> entryStream = map.entrySet().stream(); //Arrays can generate streams through the static method of(T... values) of the Stream interface String[] strArray = {"hello","world","java"}; Stream<String> strArrayStream = Stream.of(strArray); Stream<String> strArrayStream2 = Stream.of("hello", "world", "java"); Stream<Integer> intStream = Stream.of(10, 20, 30); } }
2.3 Stream Flow Intermediate Operation Method [Application]
-
concept
Intermediate operations mean that after this method is executed, Stream streams can continue to perform other operations.
-
Common methods
Method name Explain Stream filter(Predicate predicate) Data filtering in convection Stream limit(long maxSize) Returns the stream of elements in this stream, intercepting the data of the number of parameters specified before Stream skip(long n) Skipping the data of the specified number of parameters, returns a stream consisting of the remaining elements of the stream static Stream concat(Stream a, Stream b) Merge two streams a and b into one stream Stream distinct() Returns a stream consisting of different elements of the stream (according to Object.equals(Object)). Stream sorted() Returns a stream of elements from the stream, sorted in natural order Stream sorted(Comparator comparator) Returns a stream consisting of elements of the stream, sorted according to the provided Comparator Stream map(Function mapper) Returns a stream consisting of the results of the elements applied to the stream by a given function IntStream mapToInt(ToIntFunction mapper) Returns an IntStream containing the result of applying the given function to the element of the stream -
Demonstration of filter code
public class StreamDemo01 { public static void main(String[] args) { //Create a collection that stores multiple string elements ArrayList<String> list = new ArrayList<String>(); list.add("Lin Qingxia"); list.add("Zhang Manyu"); list.add("Wang Zuxian"); list.add("Liu Yan"); list.add("Aman Chang"); list.add("Zhang Wuji"); //Requirement 1: Output the elements in the list set that begin with the opening in the console list.stream().filter(s -> s.startsWith("Zhang")).forEach(System.out::println); System.out.println("--------"); //Requirement 2: Output the 3-length element in the list set in the console list.stream().filter(s -> s.length() == 3).forEach(System.out::println); System.out.println("--------"); //Requirement 3: Output the elements in the list set beginning with the open and length 3 in the console list.stream().filter(s -> s.startsWith("Zhang")).filter(s -> s.length() == 3).forEach(System.out::println); } }
-
Limit & skip code demonstration
public class StreamDemo02 { public static void main(String[] args) { //Create a collection that stores multiple string elements ArrayList<String> list = new ArrayList<String>(); list.add("Lin Qingxia"); list.add("Zhang Manyu"); list.add("Wang Zuxian"); list.add("Liu Yan"); list.add("Aman Chang"); list.add("Zhang Wuji"); //Requirement 1: Take the first three data to output in the console list.stream().limit(3).forEach(System.out::println); System.out.println("--------"); //Requirement 2: Skip three elements and output the remaining elements in the console list.stream().skip(3).forEach(System.out::println); System.out.println("--------"); //Requirement 3: Skip two elements and output the first two of the remaining elements in the console list.stream().skip(2).limit(2).forEach(System.out::println); } }
-
Concat & distinct code demonstration
public class StreamDemo03 { public static void main(String[] args) { //Create a collection that stores multiple string elements ArrayList<String> list = new ArrayList<String>(); list.add("Lin Qingxia"); list.add("Zhang Manyu"); list.add("Wang Zuxian"); list.add("Liu Yan"); list.add("Aman Chang"); list.add("Zhang Wuji"); //Requirement 1: Take the first four data to form a stream Stream<String> s1 = list.stream().limit(4); //Requirement 2: Skip two data to form a stream Stream<String> s2 = list.stream().skip(2); //Requirement 3: Merge the flow from Requirement 1 and Requirement 2 and output the results in the console // Stream.concat(s1,s2).forEach(System.out::println); //Requirement 4: Combine the flow from requirement 1 and requirement 2, and output the result in the console, requiring that string elements cannot be duplicated Stream.concat(s1,s2).distinct().forEach(System.out::println); } }
-
sorted code demonstration
public class StreamDemo04 { public static void main(String[] args) { //Create a collection that stores multiple string elements ArrayList<String> list = new ArrayList<String>(); list.add("linqingxia"); list.add("zhangmanyu"); list.add("wangzuxian"); list.add("liuyan"); list.add("zhangmin"); list.add("zhangwuji"); //Requirement 1: Alphabetically output data to the console // list.stream().sorted().forEach(System.out::println); //Requirement 2: Output data in console according to string length list.stream().sorted((s1,s2) -> { int num = s1.length()-s2.length(); int num2 = num==0?s1.compareTo(s2):num; return num2; }).forEach(System.out::println); } }
-
Demonstration of map & mapToInt code
public class StreamDemo05 { public static void main(String[] args) { //Create a collection that stores multiple string elements ArrayList<String> list = new ArrayList<String>(); list.add("10"); list.add("20"); list.add("30"); list.add("40"); list.add("50"); //Requirement: Convert string data in a collection to integers and output it in the console // list.stream().map(s -> Integer.parseInt(s)).forEach(System.out::println); // list.stream().map(Integer::parseInt).forEach(System.out::println); // list.stream().mapToInt(Integer::parseInt).forEach(System.out::println); //int sum() returns the sum of elements in this stream int result = list.stream().mapToInt(Integer::parseInt).sum(); System.out.println(result); } }
2.4 Stream Flow Termination Operation Method [Application]
-
concept
The end operation means that after this method is executed, the Stream stream will no longer be able to perform other operations.
-
Common methods
Method name Explain void forEach(Consumer action) Perform operations on each element of this flow long count() Returns the number of elements in this stream -
Code demonstration
public class StreamDemo { public static void main(String[] args) { //Create a collection that stores multiple string elements ArrayList<String> list = new ArrayList<String>(); list.add("Lin Qingxia"); list.add("Zhang Manyu"); list.add("Wang Zuxian"); list.add("Liu Yan"); list.add("Aman Chang"); list.add("Zhang Wuji"); //Requirement 1: Export the elements in the collection to the console // list.stream().forEach(System.out::println); //Requirement 2: There are several elements in the statistical set that begin with the opening and output the statistical results in the console. long count = list.stream().filter(s -> s.startsWith("Zhang")).count(); System.out.println(count); } }
2.5 Stream Flow Comprehensive Exercise [Application]
-
Case requirements
There are now two sets of ArrayList s that store the names of six actors and six actresses, respectively. The following operations are required
-
An actor needs only the first three men whose name is three words.
-
The actress only needs Lin's surname, and not the first one.
-
Combine the filtered names of actors and actresses
-
Create an actor object and traverse the data using the elements from the previous step as parameters of the constructor
The actor class Actor has been provided with a member variable, a parametric construction method, and a get/set method corresponding to the member variable.
-
-
code implementation
public class Actor { private String name; public Actor(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } } public class StreamTest { public static void main(String[] args) { //Create collections ArrayList<String> manList = new ArrayList<String>(); manList.add("Zhou Runfa"); manList.add("Jackie Chan"); manList.add("Lau Andy"); manList.add("Wu Jing"); manList.add("Zhou Xingchi"); manList.add("Jet Li"); ArrayList<String> womanList = new ArrayList<String>(); womanList.add("Lin Xinru"); womanList.add("Zhang Manyu"); womanList.add("Lin Qingxia"); womanList.add("Liu Yan"); womanList.add("Lin Zhiling"); womanList.add("Wang Zuxian"); /* //An actor needs only the first three men whose name is three words. Stream<String> manStream = manList.stream().filter(s -> s.length() == 3).limit(3); //The actress only needs Lin's surname, and not the first one. Stream<String> womanStream = womanList.stream().filter(s -> s.startsWith("Skp (1); //Combine the filtered names of actors and actresses Stream<String> stream = Stream.concat(manStream, womanStream); //Create an actor object and traverse the data using the elements from the previous step as parameters of the constructor // stream.map(Actor::new).forEach(System.out::println); stream.map(Actor::new).forEach(p -> System.out.println(p.getName())); */ Stream.concat(manList.stream().filter(s -> s.length() == 3).limit(3), womanList.stream().filter(s -> s.startsWith("Forest")).skip(1)).map(Actor::new). forEach(p -> System.out.println(p.getName())); } }
2.6 Stream Flow Collection Operation [Application]
-
concept
After the data is manipulated by Stream stream, the data in the stream can be collected into the collection.
-
common method
Method name Explain R collect(Collector collector) Collect results into collections -
Tool class Collectors provides specific collection methods
Method name Explain public static Collector toList() Collect elements into List collections public static Collector toSet() Collect elements into Set collections public static Collector toMap(Function keyMapper,Function valueMapper) Collect elements into Map collections -
Code demonstration
public class CollectDemo { public static void main(String[] args) { //Create List Collection Objects List<String> list = new ArrayList<String>(); list.add("Lin Qingxia"); list.add("Zhang Manyu"); list.add("Wang Zuxian"); list.add("Liu Yan"); /* //Requirement 1: Get a stream with three names Stream<String> listStream = list.stream().filter(s -> s.length() == 3); //Requirement 2: Collect data that has been manipulated using Stream streams into a List collection and traverse it List<String> names = listStream.collect(Collectors.toList()); for(String name : names) { System.out.println(name); } */ //Create Set Collection Objects Set<Integer> set = new HashSet<Integer>(); set.add(10); set.add(20); set.add(30); set.add(33); set.add(35); /* //Demand 3: Get flows older than 25 Stream<Integer> setStream = set.stream().filter(age -> age > 25); //Requirement 4: Collect data from Stream stream operations into Set collections and traverse them Set<Integer> ages = setStream.collect(Collectors.toSet()); for(Integer age : ages) { System.out.println(age); } */ //Define an array of strings, each of which is composed of name data and age data String[] strArray = {"Lin Qingxia,30", "Zhang Manyu,35", "Wang Zuxian,33", "Liu Yan,25"}; //Requirement 5: Get a stream with age data greater than 28 in the string Stream<String> arrayStream = Stream.of(strArray).filter(s -> Integer.parseInt(s.split(",")[1]) > 28); //Requirement 6: Collect data from Stream stream operation into Map set and traverse it. Name in string is used as key and age is used as value. Map<String, Integer> map = arrayStream.collect(Collectors.toMap(s -> s.split(",")[0], s -> Integer.parseInt(s.split(",")[1]))); Set<String> keySet = map.keySet(); for (String key : keySet) { Integer value = map.get(key); System.out.println(key + "," + value); } } }