Seventeen, JDK8 new features (end)
Seventeen, JDK8 new features
17.1 Introduction to lambda expressions
17.1.1 Lambda operation case
Look at the case first:
package com.itheima.lambda;
/**
* @author: Carl Zhang
* @create: 2021-12-31 14:57
* Experience the difference between Lambda expressions and traditional expressions
* Practice swimming
*/
public class Lambda01 {
public static void main(String[] args) {
/*
* Conclusion: 1.The traditional anonymous inner class method solves the problem of interface arguments, it is necessary to create an anonymous inner class object, implement the interface method, two steps--focus on how to do it
* 2.Lambda expressions only need one expression, code introduction, and the focus is more clear on the method function and output--focus on what to do
* 3.This idea of focusing on what the method can do is the idea of functional programming
* */
//The traditional method implements swimming-anonymous inner class
swim(new Swim() {
@Override
public void swimming() {
System.out.println("Swimming of anonymous inner classes....");
}
});
//implementation of Lambda operation
swim(()-> System.out.println("Swimming of anonymous inner class...."));
}
public static void swim (Swim swim) {
swim.swimming();
}
}
interfaceSwim {
/**
* Swim
* */
void swimming();
}
Note: The lambda
expression can be understood as a simplification of anonymous inner classes, but the essence is different
17.1.2 Introducing the idea of functional programming
Introduction:
- In mathematics, a function is a set of calculation schemes with input and output, that is, "operating with data"
- And
lambda
is a reflection of the idea of functional programming
17.1.3 Comparison of functional programming ideas and object-oriented programming ideas
- Object-oriented thinking:
- The emphasis is on using objects to accomplish certain functions--how
- Functional programming ideas:
- emphasizes results, not how to do--what to do
17.2 Functional Interface
17.2.1 Functional Interface Introduction
-
Concept:
- An interface that has only one abstract method requires overriding is a functional interface,
- Functional interfaces allow other non-abstract methods such as static methods, default methods, private methods,
-
Annotation: To identify that the interface is a functional interface, a comment can be added to the interface:
@FunctionalInterface
-
Related API : The interfaces in the
java.util.function
package inJDK
are all functional interfaces
The Runnable
interface we learned before is also a functional interface
You can also customize a functional interface:
package com.itheima.lambda;
/**
* @author CarlZhang
* Customize a functional interface
*/
@SuppressWarnings("ALL")
@FunctionalInterface
public interface FunctionalInterface01 {
/**
* only one abstract method to override
*/
void method01();
/**
* Inherit the methods of the Object class
*/
@Override
String toString();
/**
* jdk1.8 interface can have static methods and default methods
* */
static void method02() {
System.out.println("Static method in FunctionalInterface01");
}
/**
* default method
* */
default void method03() {
System.out.println("Default method in FunctionalInterface01");
}
}
@FunctionalInterface
interface FunctionalInterface02 extends FunctionalInterface01{
//Error: Because there are two abstract methods to be rewritten here, one for the parent interface and one for this interface,
//Conclusion: There can only be one abstract method to be rewritten in the functional interface, and the one in the parent class interface is also counted, and the Object class is special.
//There are abstract methods that override the Object class in the interface and do not affect the determination of the functional interface
//void method02();
}
17.2.2 Precautions and usage details
- There can only be oneabstract method to be overridden in the interface, a method inherited from the
**Object**
class Except - Functional interfaces can be represented by the annotation
@FunctionalInterface
17.3 Use of lambda expressions
17.3.1 Lambda expression syntax
Standard format: (parameter list)-> {//The method body of the method to be implemented...}
17.3.2 Lambda expression use case
/**
* @author: Carl Zhang
* @create: 2021-12-31 16:32
* Exercise 1:
* 1 Write an interface (ShowHandler)
* 2 There is an abstract method (show) in this interface, which has no arguments and no return value
* 3 There is a method (useShowHandler) in the quiz class (ShowHandlerDemo)
* The argument of the method is of type ShowHandler, and the show method of ShowHandler is called inside the method
*/
public class ShowHandlerDemo {
public static void useShowHandler(ShowHandler showHandler) {
showHandler.show();
}
public static void main(String[] args) {
//Call the useShowHandler method
//Use the Lambda expression to implement the ShowHandler interface as an argument
useShowHandler(()-> {
System.out.println("Use the Lambda expression to implement the ShowHandler interface as an argument");
});
}
/*
* Lambda expression format resolution
* 1.() represents the formal parameter list of the method in the implemented interface
* 2.The-> syntax specifies the content of the method to be implemented
* 3.{} The method body of the method to be implemented
*
* Note: The interface implemented by the Lambda operation must be a functional interface
* */
}
/**
* @author CarlZhang
*/
@FunctionalInterface
public interface ShowHandler {
/**
* There is an abstract method (show) in this interface, which has no arguments and no return value
* */
void show();
}
/**
* @author: Carl Zhang
* @create: 2021-12-31 16:48
* need
* 1 First there is an interface (StringHandler)
* 2 There is an abstract method (printMessage) in this interface, which has arguments and no return value
* 3 There is a method (useStringHandler) in the quiz class (StringHandlerDemo),
* The argument of the method is of type StringHandler,
* The printMessage method of StringHandler is called inside the method
*/
public class StringHandlerDemo {
public static void useStringHandler(StringHandler stringHandler) {
stringHandler.printMessage("Hello, World");
}
public static void main(String[] args) {
//Implement StringHandler using lambda expressions, passed as arguments
//in conclusion:
//1.The content in () corresponds to the interfaceThe content of method () is a formal argument, and the lambda expression is regarded as an interface implementation class
//2.If there is only one argument, you can omit ()
useStringHandler(String s-> {
System.out.println("The code block that calls the Lambda expression " + s);
});
//implemented by anonymous inner class
useStringHandler(new StringHandler() {
@Override
public void printMessage(String s) {
System.out.println("Anonymous inner class method " + s);
}
});
}
}
@FunctionalInterface
public interface StringHandler {
/**
* There is an abstract method (printMessage) in this interface, which has arguments and no return value
* @param s any string
*/
void printMessage(String s);
}
package com.heima.lambda;
import org.omg.CORBA.PUBLIC_MEMBER;
/**
* @author Carl Zhang
* @description
* @date 2022/1/1 20:32
* 1 First there is an interface (Calculator)
* 2 There is an abstract method (calc) in this interface, which has arguments and return values
* 3 There is a method (useCalculator) in the test class (CalculatorDemo)
* The argument of the method is of type Calculator
* Called Calculator's calc method inside the method
*/
public class CalculatorDemo {
public static void useCalculator(Calculator calculator) {
System.out.println(calculator.calc(11, 12));
}
public static void main(String[] args) {
/*
* 1.There are methods with parameters and return values, directly write (formal parameter list)-> { return return value; },
* Further reflects the functional programming idea of (input)-> {output}
* 2.Argument type can be omitted, if there are multiple arguments, only one cannot be omitted
* 3.If the code block has only one sentence, you can omit braces and semicolons, or even return
* */
//useCalculator((int num1, int num2)-> {
//return num1 + num2;
//});
useCalculator((num1, num2)-> num1 + num2);
}
}
/**
* @author CarlZhang
* 1 First there is an interface (Calculator)
* 2 There is an abstract method (calc) in this interface, which has arguments and return values
*/
@FunctionalInterface
public interfaceCalculator {
/**
* Calculate the sum of two numbers
* @param num1 the first number
* @param num2 second number
* @return the sum of two numbers
*/
int calc(int num1, int num2);
}
17.3.2 Precautions and usage details
Prerequisites: The interface implemented by the Lambda
operation must be a functional interface
Format Resolution:
Lambda
The expression can be regarded as an implementation class object of the functional interface()
represents the formal parameter list of the method in the implemented interface, none can be left blank.- The type of the argument can be omitted, but only one of the multiple arguments cannot be omitted
- Only one argument can be omitted
()
->
syntax specification, pointing to the content of the method to be implemented{}
the method body of the method to be implemented- There is only one sentence in the code block, you can omit
{}
and;
, or evenreturn
The format of - There is only one sentence in the code block, you can omit
(parameter)-> {return value}
reflects the functional programming idea of (input)-> {output}
li>
17.4 The difference between lambda expressions and anonymous inner classes
- Action object is different:
- Anonymous inner class: It can be an interface, an abstract class, or a concrete class
Lambda expressions
: only functional interfaces
- Scenarios are different:
- If the interface has one and only one abstract method, you can use a
Lambda
expression or an anonymous inner class - If there is more than one abstract method in the interface, only anonymous inner classes can be used, not
Lambda
expressions
- If the interface has one and only one abstract method, you can use a
- How it works is different:
- Anonymous inner class: After compilation, a separate
.class
bytecode file is generated Lambda
expression: After compilation, there is no separate.class
bytecode file, the corresponding bytecode will be run at run strong>Dynamic generation
- Anonymous inner class: After compilation, a separate
/**
* @author Carl Zhang
* The difference between @description Lambda expressions and anonymous inner classes
* @date 2022/1/1 21:36
*/
public class LambdaVsAnonymous {
public static void main(String[] args) {
//Lambda expression calls show method--no.class file after compilation
Test test=()-> System.out.println("Hello, World");
test.show();
//Anonymous inner class calls show method--has LambdaVsAnonymous$1.class file
new Test() {
@Override
public void show() {
System.out.println("Hello, World");
}
}.show();
}
}
@FunctionalInterface
interface Test {
/**
* print method
*/
void show();
}
17.5 Stream
17.5.1 Stream's experience
import java.util.ArrayList;
/**
* @author Carl Zhang
* @description Experience the benefits of Stream
* @date 2022/1/2 17:28
* Requirements: Complete the creation and traversal of the collection according to the following requirements
* <p>
* 1 Create a collection and save multiple string elements
* "Zhang Wuji", "Zhang Cuishan", "Zhang Sanfeng", "Xie Guangkun", "Zhao Si", "Liu Neng", "Xiao Shenyang", "Zhang Liang"
* 2 Save all elements starting with "Zhang" in the collection to a new collection
* 3 Save the elements of length 3 in the set starting with "Zhang" to a new set
* 4 Traverse the collection obtained in the previous step
*/
public class Stream01 {
public static void main(String[] args) {
//method of collection
//1.Create a collection, add data
ArrayList<String> list=new ArrayList<>();
list.add("Zhang Wuji");
list.add("Zhang Cuishan");
list.add("Zhang Sanfeng");
list.add("Xie Guangkun");
list.add("Zhao Si");
list.add("Liu Neng");
list.add("Little Shenyang");
list.add("Zhang Liang");
ArrayList<String> newList=new ArrayList<>();
ArrayList<String> newList2=new ArrayList<>();
//The elements starting with "Zhang" are added to the new collection
for (String s : list) {
if (s.startsWith("Zhang")) {
//3.Elements starting with "Zhang" are added to the new collection
newList.add(s);
}
}
//"Zhang" and length 3 are added to another element
for (String s : newList) {
if (s.startsWith("Zhang") && s.length()==3) {
newList2.add(s);
}
}
//4.print
System.out.println(newList);
System.out.println(newList2);
System.out.println("===================");
//Stream stream method to obtain and print elements starting with "Zhang" and length 3--simplifying the operation of data in the container
list.stream().filter(s-> s.startsWith("Zhang") && s.length()
==3).forEach(s-> System.out.println(s));
}
}
17.5.2 Stream introduction
17.6 Stream three types of methods
17.6.1 Introduction to three types of stream methods
- Get the
Stream
stream- Create a pipeline and put the data on the pipeline to prepare for operation
- Intermediate method
- Operations on the pipeline,
- Once an operation is complete, you can continue with other operations
- Terminator
- A
Stream
stream can only have one finalizer - is the last operation on the pipeline
- A
17.6.2 Stream stream-acquisition method
- Single column collection
- Streams can be generated using the default method
stream()
in theCollection
interface default Stream<E> stream()
- Streams can be generated using the default method
- Dual column collection
- Double-column collection cannot be obtained directly, need to generate stream indirectly
- You can first obtain a
Set
collection throughkeySet
() orentrySet()
, and then obtain theStream
stream
- Array
- Static method in
Arrays
stream
generate stream
- Static method in
import java.util.*;
import java.util.stream.Stream;
/**
* @author Carl Zhang
* Get method of @description Stream stream
* @date 2022/1/2 17:59
*/
@SuppressWarnings("ALL")
public class StreamGetMethod {
public static void main(String[] args) {
//Get the Stream stream of a single-column collection
singleSetStream();
//Get the Stream stream of the two-column collection
doubleSetStream();
//Get the Stream stream of the array
arrayStream();
//Get the stream of any element--understand
int[] array={1, 2, 3, 4, 5, 6};
Stream.of(array).forEach(i-> System.out.println(i));//[I@7ba4f24f
Stream.of(1, 2, 3, 4, 5, 6).forEach(i-> System.out.println(i));
}
private static void arrayStream() {
System.out.println("Get the Stream of the array");
int[] arr={1, 2, 3, 4, 5, 6};
Arrays.stream(arr).forEach(i-> System.out.println(i));
}
private static void doubleSetStream() {
HashMap<String, String> hashMap=new HashMap<>();
hashMap.put("it001", "Cao Zhi");
hashMap.put("it002", "Cao Pi");
hashMap.put("it003", "Cao Xiong");
hashMap.put("it004", "Cao Chong");
hashMap.put("it005", "Cao Ang");
//The double-column collection cannot be obtained directly, and an indirect stream is required
//You can first obtain a Set collection through keySet or entrySet, and then obtain the Stream stream
System.out.println("Get the Stream stream of the double-column collection");
Set<Map.Entry<String, String>> entries=hashMap.entrySet();
entries.stream().forEach(entry-> System.out.println(entry.getKey() +
"-" + entry.getValue()));
}
private static void singleSetStream() {
ArrayList<String> list=new ArrayList<>();
list.add("Dilraba");
list.add("Gulinaza");
list.add("Marzaha");
list.add("Ouyang Nana");
//Streams can be generated using the default method stream() in the Collection interface
//default Stream<E> stream()
System.out.println("Get the Stream of a single-column collection");
list.stream().forEach((String s)-> {
System.out.println(s);
});
}
}
17.6.3 Stream stream-intermediate method
Features: The Stream
flow object is returned to continue calling the method to operate the flow object
Stream<T> filter(Predicate predicate)
: used to filter the data in the streamPredicate
The method in the interface:boolean test(T t)
: judge the given argument and return a boolean value
Stream<T> limit(long maxSize)
: intercept the data of the specified number of argumentsStream<T> skip(long n)
: skip the specified number of argumentsstatic <T> Stream<T> concat(Stream a, Stream b)
: combine two streams a and b into one streamStream<T> distinct()
: remove duplicate elements in the stream, depending on (hashCode and equals methods)Stream<T> sorted ()
: sort the elements in the stream according to the natural ordering rulesStream<T> sorted (Comparator<? super T> comparator)
: sort the elements in the stream according to the custom comparator rules
import java.util.ArrayList;
import java.util.Comparator;
import java.util.function.Predicate;
import java.util.stream.Stream;
/**
* @author Carl Zhang
* @description Stream intermediate method
* @date 2022/1/2 19:12
*/
@SuppressWarnings("ALL")
public class StreamCentreMethod {
public static void main(String[] args) {
ArrayList<String> list=new ArrayList<>();
list.add("Zhang Wuji");
list.add("Zhang Cuishan");
list.add("Zhang Sanfeng");
list.add("Xie Guangkun");
list.add("Zhao Si");
list.add("Liu Neng");
list.add("Little Shenyang");
list.add("Zhang Liang");
list.add("Zhang Liang");
list.add("Zhang Liang");
list.add(new String("Zhang Liang"));
//1 Stream<T> filter(Predicate predicate): used to filter the data in the stream
//Methods of the Predicate functional interface: boolean test(T t): judge the given argument and return a boolean value
//T is a generic type, the element type in the Stream stream
//Return true to stay, false to filter out
//Print elements with three-letter names in the collection
//list.stream().filter(new Predicate<String>() {
//@Override
//public boolean test(String s) {
//return s.length()==3;
//}
//}).forEach(s-> System.out.println(s));
list.stream().filter(s-> s.length()==3).forEach(s-> System.out.println(s));
//2 Stream<T> limit(long maxSize): Intercept the data of the specified number of arguments
//get the first two elements
Stream<String> stream=list.stream();
stream.limit(2).forEach(s-> System.out.println(s));
//3 Stream<T> skip(long n): skip the data with the specified number of arguments
//Skip the first two elements and print the following elements
//Exception IllegalStateException: stream has already been operated upon or closed
//stream.skip(2).forEach(s-> System.out.println(s));
list.stream().skip(2).forEach(s-> System.out.println(s));
//4 static <T> Stream<T> concat(Stream a, Stream b): Combine two streams a and b into one stream
ArrayList<String> list2=new ArrayList<>();
list2.add("Dilraba");
list2.add("Gulinaza");
list2.add("Ouyang Nana");
list2.add("Marzaha");
Stream.concat(list.stream(), list2.stream()).forEach(s-> System.out.println(s));
//5 Stream<T> distinct(): remove duplicate elements in the stream, depending on (hashCode() and equals())
list.stream().distinct().forEach(s-> System.out.println(s));
//There is only one "Zhang Liang" left, because the method in String returns the hashCode according to the value of value
//new String("Zhang Liang").hashCode();
//6 Stream<T> sorted () : sort the elements in the stream according to the natural sorting rules
list.stream().sorted().forEach(s-> System.out.println(s));
//7 Stream<T> sorted (Comparator<? super T> comparator) : sort the elements in the stream according to the custom comparator rules
list.stream().sorted(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o2.length()-o1.length();
}
}).forEach(s-> System.out.println(s));
System.out.println();
list.stream().sorted((s1, s2)-> s2.length()-s1.length()).forEach(
s-> System.out.println(s)
);
}
}
17.6.4 Stream stream-termination method
Features: Generous training, pass value, cannot continue to call method to operate flow object
void forEach(Consumer action)
: perform an action on each element of this streamConsumer
method in interfacevoid accept(T t)
: perform this operation on the given argument
long count()
: returns the number of elements in this stream
import java.util.ArrayList;
import java.util.function.Consumer;
/**
* @author Carl Zhang
* @description Stream finalizer
* @date 2022/1/2 19:48
*/
public class StreamEndMethod {
public static void main(String[] args) {
ArrayList<String> list=new ArrayList<>();
list.add("Zhang Wuji");
list.add("Zhang Cuishan");
list.add("Zhang Sanfeng");
list.add("Xie Guangkun");
//1 void forEach(Consumer action): perform an action on each element of this stream
//Method in the Consumer interface void accept(T t): perform this operation on the given argument
//Put the elements in the list collection into the stream
//The forEach method loops through the data in the stream
//And call the accept method in a loop to pass the data to s
//So s represents each data in the stream
//We only need to do business logic processing on the data in the accept method
list.stream().forEach(s-> System.out.println(s));
//2.long count(): returns the number of elements in this stream
//result: 4
System.out.println(list.stream().count());
}
}
17.7 Stream collection method
17.7.1 Reason for using the collection method
Question: After using the Stream
stream, I want to retrieve the data in the stream, what should I do?
Extract the collection method
package com.heima.stream;
import java.util.ArrayList;
/**
* @author Carl Zhang
* @description the reason for using the collection method
* @date 2022/1/2 20:04
* Requirements: filter elements and traverse the collection
* Define a set and add some integers 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
* wash out the odd numbers in the collection, keep only the even numbers,
* Traverse the collection to get 2, 4, 6, 8, 10
*/
public class CollectionMethod01 {
public static void main(String[] args) {
//JDK9 new features directly pass in the elements of an immutable collection to create a new collection
//ArrayList<Integer> list=new ArrayList<>(List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
ArrayList<Integer> list=new ArrayList<>();
for (int i=1; i <=10; i++) {
list.add(i);
}
//Use Stream to filter out odd numbers in the collection and get even numbers
list.stream().filter(i-> i % 2==0).forEach(i-> System.out.println(i));
//Conclusion: The number in the list set has not changed
//If you need to keep the filtered elements in the stream-> use the collection method
System.out.println(list);
}
}
17.7.2 Introduction to Collection Methods
Stream
Stream collection method
R collect(Collector collector)
: This method is only responsible for collecting data in the stream, creating a collection and adding data actions need to rely on arguments
The collection method can also be regarded as a termination method.After calling collect()
, the Stream
object will not be returned, and the stream cannot be operated again
17.7.2 Three collection methods
The tool class Collectors
provides specific collection methods
public static <T> Collector toList()
: collect elements into the List collection
public static <T> Collector toSet()
: collect elements into a Set collection
package com.heima.stream;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collector;
import java.util.stream.Collectors;
/**
* @author Carl Zhang
* @description Stream collection method
* @date 2022/1/2 20:22
* need :
* Define a set and add some integers 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
* wash out the odd numbers in the collection, keep only the even numbers,
* Traverse the collection to get 2, 4, 6, 8, 10
*/
public class CollectionMethod02 {
public static void main(String[] args) {
ArrayList<Integer> list=new ArrayList<>();
for (int i=1; i <=10; i++) {
list.add(i);
}
//Get the filtered elements through the collection method
//resolution:
//1.R collect(Collector collector) : This method is only responsible for collecting data in the stream.The action of creating a collection and adding data needs to rely on arguments
//2.Save the collected elements to the collection through the rules in the tool class Collector
//public static <T> Collector toList(): Collect elements into the List collection
List<Integer> list1=list.stream().filter(i-> i % 2==0).collect(
Collectors.toList());
System.out.println(list1);//[2, 4, 6, 8, 10]
//Collect the filtered elements into the Set collection
//public static <T> Collector toSet(): Collect elements into the Set collection
Set<Integer> set=list.stream().filter(i-> i % 2==0).collect(
Collectors.toSet()
);
System.out.println(set);//[2, 4, 6, 8, 10]
}
}
public static Collector toMap(Function keyMapper,Function valueMapper)
: collect elements into the Map collection
import java.util.ArrayList;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @author Carl Zhang
* @description collects the filtered elements into the Map collection
* @date 2022/1/2 20:33
* public static Collector toMap(Function keyMapper, Function valueMapper):
* Collect elements into a Map collection
* <p>
* 1 Create an ArrayList collection, and add the following strings, the name is in front of the string, and the age is in the back
* "zhangsan,23"
* "lisi,24"
* "wangwu,25"
* 2 Retain people whose age is greater than or equal to 24, and collect the results into a Map collection, with the name as the key and age as the value
*/
public class CollectionMethod03 {
public static void main(String[] args) {
ArrayList<String> list=new ArrayList<>();
list.add("zhangsan,23");
list.add("lisi,24");
list.add("wangwu,25");
//Filter out elements over 24 years old
Stream<String> stream=list.stream().filter(s-> {
String[] split=s.split(",");
//get age
int age=Integer.parseInt(split[1]);
//Filter out those who are greater than or equal to 24 years old
atorvastatin 40mg ca & lt;a href="https://lipiws.top/"& gt;buy lipitor 10mg online& lt;/a& gt; atorvastatin ca
Cnbcdj
2024-03-08