Syntax of Lambda expressions
Basic syntax:
(parameters) -> expression or (parameters) ->{ statements; } Copy code
Method reference
There are three kinds of method references. Method references are represented by a pair of double colons::. Method references are another writing method of functional interfaces
- Static method reference, through class name:: static method name, such as Integer::parseInt
- Instance method reference, through instance object:: instance method, such as str::substring
- You can also class name:: instance method name, such as String::substring
- Construct method reference through class name:: new, such as User::new
Third point: if the first parameter in Lambda's parameter list is the caller of the instance method and the second parameter (or no parameter) is the parameter of the instance method, the format is: Class Name:: instance method name
There are several basic function shapes,
including Function (unary function from T to R), Consumer (unary function from T to void), Predicate (unary function from T to boolean), and Supplier (nullary function to R).
Function shapes have a natural arity based on how they are most commonly used. The basic shapes can be modified by an arity prefix to indicate a different arity, such as BiFunction (binary function from T and U to R).
Class name:: method name, which is equivalent to a reference to this method closure, similar to a function in js. For example:
public static void main(String[] args) { Consumer<String> printStrConsumer = DoubleColon::printStr; printStrConsumer.accept("printStrConsumer"); Consumer<DoubleColon> toUpperConsumer = DoubleColon::toUpper; toUpperConsumer.accept(new DoubleColon()); BiConsumer<DoubleColon,String> toLowerConsumer = DoubleColon::toLower; toLowerConsumer.accept(new DoubleColon(),"toLowerConsumer"); BiFunction<DoubleColon,String,Integer> toIntFunction = DoubleColon::toInt; int i = toIntFunction.apply(new DoubleColon(),"toInt"); } static class DoubleColon { public static void printStr(String str) { System.out.println("printStr : " + str); } public void toUpper(){ System.out.println("toUpper : " + this.toString()); } public void toLower(String str){ System.out.println("toLower : " + str); } public int toInt(String str){ System.out.println("toInt : " + str); return 1; } } Copy code
The main difference between static and non-static methods is that non-static methods have one more parameter than static methods, that is, the called instance.
// Use double colons:: to construct non static function references String content = "Hello JDK8"; // public String substring(int beginIndex) // Writing method 1: object:: non static method Function<Integer, String> func = content::substring; String result = func.apply(1); System.out.println(result); // Method 2: IntFunction<String> intFunc = content::substring; result = intFunc.apply(1); System.out.println(result); // Writing method 3: String:: non static method BiFunction<String,Integer,String> lala = String::substring; String s = lala.apply(content, 1); System.out.println(s); // public String toUpperCase() // Writing method 1: function reference is also a functional interface, so function reference can also be used as a method parameter Function<String, String> func2 = String::toUpperCase; result = func2.apply("lalala"); System.out.println(result); // Writing method 2: it can be rewritten as Supplier: enter the parameter void and return the value String Supplier<String> supplier = "alalal"::toUpperCase; result = supplier.get(); System.out.println(result); Copy code
Array reference
// Traditional Lambda implementation IntFunction<int[]> function = (i) -> new int[i]; int[] apply = function.apply(5); System.out.println(apply.length); // 5 // Array type reference implementation function = int[]::new; apply = function.apply(10); System.out.println(apply.length); // 10 Copy code
Optional usage
c static void main(String[] args) { // The Optional class has become a part of the Java 8 class library and has been in Guava for a long time. Maybe Oracle is used directly // Optional is used to solve the null pointer exception, make the code more rigorous, and prevent the null pointer NullPointerException from affecting the code String msg = "hello"; Optional<String> optional = Optional.of(msg); // Judge whether there is a value; it cannot be blank boolean present = optional.isPresent(); // If there is a value, return the value. If it is equal to null, throw an exception String value = optional.get(); // If empty, returns the value specified by else String hi = optional.orElse("hi"); // If the value is not empty, the Lambda expression is executed optional.ifPresent(opt -> System.out.println(opt)); Copy code
Some operations of Stream
Some streams can be converted into collections. For example, toList mentioned earlier generates Java util. An instance of the list class. Of course, there are toSet and toCollection, which generate instances of Set and Collection classes respectively.
final List<String> list = Arrays.asList("jack", "mary", "lucy"); // Filter + output System.out.println("filter + output: "); Stream<String> stream = list.stream(); stream.filter(item -> !item.equals("zhangsan")) .filter(item -> !item.equals("wangwu")) .forEach(item -> System.out.println(item)); // Limit to 2 System.out.println("limit(2): "); list.stream().limit(2).forEach(System.out::println); // sort System.out.println("sort: "); list.stream().sorted((o1, o2) -> o1.compareTo(o2)).forEach(System.out::println); // Take out the maximum value System.out.println("max: "); String result = list.stream().max((o1, o2) -> o1.compareTo(o2)).orElse("error"); System.out.println(result); // toList System.out.println("toList: "); List<Integer> collectList = Stream.of(1, 2, 3, 4) .collect(Collectors.toList()); System.out.println("collectList: " + collectList); // Print results // collectList: [1, 2, 3, 4] // toSet System.out.println("toSet: "); Set<Integer> collectSet = Stream.of(1, 2, 3, 4) .collect(Collectors.toSet()); System.out.println("collectSet: " + collectSet); // Print results // collectSet: [1, 2, 3, 4] Copy code
list to map (via stream)
List<Person> list = new ArrayList<>(); list.add(new Person(1, "mary")); list.add(new Person(2, "lucy")); Map<Integer, Person> map = list.stream().collect(Collectors.toMap(Person::getId, Function.identity())); System.out.println(map); // Output: {1=Main3$Person@42f30e0a, 2=Main3$Person@24273305 } Map<Integer, String> map2 = list.stream().collect(Collectors.toMap(Person::getId, Person::getName)); System.out.println(map2); // Output: {1=mary, 2=lucy} Copy code
Split data block
Map<Boolean, List<Integer>> map = Stream.of(1, 2, 3, 4) .collect(Collectors.partitioningBy(item -> item > 2)); System.out.println(map); // Output: {false=[1, 2], true=[3, 4]} Copy code
The return value of the function can only divide the data into two groups, that is, true and false.
Block data
Data grouping is a more natural data segmentation operation. Different from dividing data into true and false parts, you can use any value to group data.
Groupingby is to group all sets. The result after grouping is like map < key, list >. Among them, key is the field type for grouping. For example, it is grouped by type (user type: 1, 2, 3, 4) in Ussr class. The type of type is Integer, and the key type of the map after grouping is Integer. It can be divided into four groups at most, so the final result is map < Integer, list >. Suppose we want to group a set with user type 1, for example: Map < Integer, list < user > > usermap = alluserlist parallelStream(). collect(Collectors.groupingBy(User::getType)); Next, you can directly get (1) from the map, such as: List < user > userlist = usermap get(1);
Pit between groupingBy and partitioningBy
1. It must be mentioned that during get, the groupingBy group will return null if the key does not exist, and the partitioningBy group will return an empty array. Note that the groupingBy group should be null.
2. The efficiency of stream processing set is not necessarily higher than that of iterator. If sequence is not required, parallel stream can be used for parallel stream processing.
character string
In Java 1.8, we can use Stream to implement. Here we will use collectors Joining collects the values in the Stream. This method can easily get a string from the Stream. The joining function accepts three parameters, which are allowed (to separate elements), prefix and suffix.
String strJoin = Stream.of("1", "2", "3", "4") .collect(Collectors.joining(",", "[", "]")); System.out.println("strJoin: " + strJoin); // Print results // strJoin: [1,2,3,4] Copy code