Oracle now officially releases a new VERSION of the JDK every six months. According to the time, JDK15 will be released this month. However, most companies are still using JDK7 and 8.
I went to my friend’s house and was ridiculed for not being able to use JDK8. Unconvinced, I came back, of course, is the focus of learning ah.
Directory:
- Lambda expressions
- Interface default methods and static methods
- Functional interface
- Method references
- Optional
- Stream API
- Date time new API
Lambda expressions
Let’s look at how lambda expressions are defined:
A lambda expression is an anonymous function. Lambda expressions allow a function to be passed as an argument.
May just see these two sentences, do not know what is meant. You can get a feel for this by comparing the use of setInterval in JS.
// Execute an anonymous function every second. (analog clock) setInterval(function() {console.log(" current time: "+ new Date())); }, 1000); Copy the codeCopy the code
Function (){} is an anonymous function and can be passed as an argument to the setInterval function.
This is because, in JS, functions are first-class citizens.
In Java, however, objects are first-class citizens. However, in JDK8 we can express the same effect with lambda expressions.
The syntax for lambda expressions is as follows:
(Parameter 1, parameter 2) -> {method body} copies the codeCopy the code
The left side specifies all the parameters needed for a lambda expression, and the right side describes the method body. -> is the lambda operator.
Think about how we started a thread with an anonymous inner class.
public class LambdaTest { @Test public void test(){ new Thread(new Runnable() { @Override public void run() { System.out.println(" Thread running...") ); } }).start(); }} Copy the codeCopy the code
Now, if you change it to lambda expressions,
Public class LambdaTest {@test public void Test (){new Thread(()-> system.out.println (" Thread running..."); )).start(); }} Copy the codeCopy the code
And you can see that lambda is obviously a little bit more concise.
In fact, Lambda expressions are the embodiment of functional programming. What, you still don’t know what functional programming is? That still don’t hurry baidu go.
Matters needing attention:
-
The data type of the parameter list is automatically inferred. In other words, if an anonymous function has an argument list, it only needs to write the name of the argument, not the type of the argument.
-
If the argument list is empty, the left side only needs to be bracketed.
-
If there is only one argument, you can omit the parentheses and write only the name of the argument.
-
If there is only one execution statement in the method body, you can omit the brace on the right. If there is a return value, omit both the return and the brace.
Interface default methods and static methods
Default interface methods
As we know, in Java interface, can only define the method name, can not implement the method body, the concrete implementation needs to subclass to do.
However, things are different in JDK8. In the interface, the method body can also be implemented with the default keyword.
Well, there’s a little bit of confusion. Well, why add this weird feature and what does it do?
To improve code reuse, of course. In addition, the default method of the interface can be extended without affecting the original inheritance system, and realize the backward compatibility of the interface.
Oh, my God, it’s so abstract. Well, let’s use an example to illustrate.
Suppose that the succession of animals is as follows,
Public interface Animal {// All animals need to eat. Void eat(); } public implements Animal {@override public void eat() {system.out.println (" Bird implements Animal "); ); }} public implements Animal {@override public void eat() {system.out.println (" implements Animal "); ); }} Copy the codeCopy the code
Now it’s time to extend the Animal interface. An animal can’t just eat, it may run, it may fly. So, I’ll just add two methods to the interface, run and fly.
It’s okay to define the method this way, but here’s the problem. The interface defines methods, and the implementation class implements all of its methods. Kittens can run, but they can’t fly. And the bird can fly, you let it run on the ground is not injustice.
So, this design is not very reasonable.
At this point, you can define default methods in the interface. Subclasses do not need to implement all methods and can implement them on demand or simply use the default methods of the interface.
So, modify the Animal interface as follows, make run and fly the default methods,
Public interface Animal {// All animals need to eat. Void eat(); Default void run(){system.out.println (" I run "); } default void fly(){system.out.println (" I "); } } public class Main { public static void main(String[] args) { Bird bird = new Bird(); bird.fly(); Cat cat = new Cat(); cat.run(); }} Copy the codeCopy the code
In addition, static methods can be defined in the interface. In this way, static methods can be called directly from the interface name. (This is also normal; the interface cannot be instantiated.)
Note that static methods of an interface cannot be called from an object that implements the class.
Public interface MyStaticInterface {static void method(){system.out.println (" this is the static method "); } } public class MyStaticInterfaceImpl implements MyStaticInterface { public static void main(String[] args) { Mystaticinterface.method (); // Call a static method directly from the interface name, not from the object implementing the class. }} Copy the codeCopy the code
Functional interface
If there is only one abstract method in an interface, it is called a functional interface. You can use the @functionalInterface annotation to check if an interface is functional.
The JDK provides four of the simplest functional interfaces in common use:
- A Consumer interface. Receives an argument, with no return value. Void accept(T T);
- Supplier, the Supplier interface. No arguments, return value. T get();
- Function
,>
, Function interface. Takes an argument and returns a result. The method is: R apply(T T);
- Predicate, Predicate interface. Accepts a parameter and returns a Boolean value. Boolean test(T T);
I’ve given you an example of how to use them,
Public class LambdaTest {@test public void test2(){printMsg((s)-> Println (s); system.out.println (s); } public void printMsg(Consumer<String> Consumer,String MSG){consumer.accept(MSG); } @test public void test3(){// Return a Random number from 0 to 99 Integer Content = getContent(() -> new Random().nextint (100)); System.out.println(content); } public Integer getContent(Supplier<Integer> Supplier){// Supplier<Integer> Supplier; } @test public void test4(){// Pass in a string and convert it all to uppercase. System.out.println(transfer((str) -> str.toUpperCase(), "My wechat : mistyskys")); } public String transfer(Function<String,String> func,String STR){ Return func. Apply (STR); } @test public void test5(){// Define a list to be used to filter ArrayList<String> list = new ArrayList<>(); list.add("zhangsan"); list.add("lisi"); list.add("jerry"); list.add("tom"); // Filter out the set with strings longer than 3 and add them to the result set. List<String> filterResult = filter((str) -> str.length() > 3, list); System.out.println(filterResult.toString()); } public List<String> filter(Predicate<String> predicate, List<String> list){ List<String> result = new ArrayList<>(); For (String STR: list) {// Predicate, passing in an argument and returning true or false. // The logic here is that if the assertion is true, the current string is added to the result set if(predicate. Test (STR)){result.add(STR); } } return result; }} Copy the codeCopy the code
There are other functional interfaces that you can look at yourself under the java.util.function package. The use method is the same, no further details.
In addition, there are many functional interfaces in the JDK, such as comparator.java. Whenever you see the @functionalInterface annotation above a class, you can use lambda expressions to simplify the notation.
4. Method reference
Concept: A method reference is an existing method or constructor used to directly access a class or instance.
To emphasize the meanings that already exist. Lambda expressions are essentially anonymous functions. Functions, we know, do logic: take some data and do something.
If we find another place (class or object) where the same logical processing scheme already exists, we can refer to its scheme without having to write the logic again. This is the method reference.
A method reference is just another, more concise way of expressing a lambda expression. Grammar sugar, if you like.
However, lambda expressions are required to meet certain requirements. First, the method body is a single line of code. Second, the implementation of the method already exists. At this point, you can replace the lambda expression with a method reference.
Method references the double colon :: operator.
Here is an example of a simple print statement that is very common.
Lambda expression String[] arr = new String[]{"zhangsan","lisi"}; Arrays.asList(arr).forEach((s)-> System.out.println(s)); Copy the codeCopy the code
As you can see, the lambda expression is a single line of code and the method body logic is a print string. The println() method already exists in the System.out object.
So lambda expressions can be replaced with method references here.
// Note: Method names in method references cannot be parenthesized. Arrays.asList(arr).forEach(System.out::println); Copy the codeCopy the code
Method references take the following four forms:
- Object :: instance method
- Class :: static methods
- Class :: instance methods
- Class: : new
Here are some examples:
Public class ReferTest {public static void main(String[] args) {public static void main(String[] args) { Must be consistent with the method parameter list and return value type corresponding to the method reference (except for case 3, which is special). / / = = = = = = = 1. Object: : instance methods = = = = = = = = = / / lambda expressions Consumer consumer1 = (s) - > System. Out. The println (s); consumer1.accept("hello world"); // Method reference. The accept method for Consumer, like the println method for system. out, takes an argument and returns no value. Therefore, it can be referenced by method. Consumer consumer2 = System.out::println; consumer2.accept("hello java"); / / = = = = = = = (2) classes: : static method = = = = = = = = = Integer [] arr = new Integer [],20,15 {12}; List<Integer> list = Arrays.asList(arr); <Integer> com1 = (o1, o2) -> Integer.com (o1, o2); // lambda expression Comparator<Integer> com1 = (o1, o2) -> Integer.com (o1, o2); Collections.sort(list,com1); // Method reference. Compare: returns an int; compare: returns an int; compare: returns an int; compare: returns an int; Comparator<Integer> com2 = Integer::compare; Collections.sort(list,com2); / / = = = = = = = 3. The class: : instance methods = = = = = = = = = / / lambda expressions Comparator < Integer > = com3 (o1, o2) - > o1.com pareTo (o2); // Method reference. (o1, O2) -> o1.compareTo(O2), // The first parameter o1 is the call object, and the second parameter o2 is the parameter that needs to reference the method. Comparator<Integer> com4 = Integer::compareTo; / / = = = = = = = 4 categories: : new = = = = = = = = = / / lambda expressions: Supplier < String > supplier1 = () - > new String (); // Method reference. This is the simpler one, the constructor reference of the class, which is used to create objects. Supplier<String> supplier2 = String::new; }} Copy the codeCopy the code
Off-topic: Method citation, sometimes not very easy to understand, let a person feel puzzling. So, lambda expressions are fine if you’re not familiar with them. It’s just a matter of habit. I feel it when I write more.
Five, the Optional
The Optional class is a container class. In the past we used null to indicate that a value does not exist. Now we can use Optional to indicate that a value does or does not exist.
The purpose of this is to prevent NullPointerException.
As we know, for objects with a deep hierarchy, it is easy to have a null pointer in the middle of the call, as shown in the following code.
User User = new User(); String details = user.getAddress().getDetails(); String details = user.getAddress(). Copy the codeCopy the code
Where, the relationship of objects is as follows,
Public class Address {private String type; // private String City; // city private String county; // private String details; Public String gettype () {return type; } public void setProvince(String province) { this.province = province; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getCounty() { return county; } public void setCounty(String county) { this.county = county; } public String getDetails() { return details; } public void setDetails(String details) { this.details = details; Public class User {private String name; private Address address; public String getName() { return name; } public void setName(String name) { this.name = name; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; }} Copy the codeCopy the code
Before the Optional class, you could do this to prevent null pointer exceptions. (Add null-detection for each layer)
private static String getUserAddr(User user){ if(user ! = null){ Address address = user.getAddress(); if(address ! = null){ return address.getDetails(); }else {return "Address info not filled in "; }}else {return "Address information is not filled in "; }} Copy the codeCopy the code
As you can see, the code is verbose, not maintainable, and can become a disaster as the hierarchy gets deeper (remember the js callback hell?).
So, with the Optional class, we can write more elegant code and prevent null-pointer exceptions. (Fill in the pit behind)
Let’s take a look at Optional options.
Create an Optional object
In fact, Optional is a wrapper around the original value (object), as you can see from the Optional source code.
It encapsulates the object T that you really need to manipulate as a value property. The constructor is privatized and provides three static methods for creating Optional objects.
Public final class Optional<T> {//EMPTY represents an Optional object with an EMPTY value. > EMPTY = new Optional<>(); Private final T value; Private Optional() {this.value = null; } // requireNonNull {private Optional(T value) {this.value = objects.requirenonNULL (value); Public static <T> requireNonNull(T obj) {if (obj == null) throw new NullPointerException(); return obj; Public static<T> Optional<T> empty() {@suppressWarnings ("unchecked") Optional<T> T = (Optional<T>) EMPTY; return t; Public static <T> Optional<T> of(T value) {return new Optional<>(value); } // create an Optional object with an Optional value that is null. 2 public static <T> Optional<T> ofNullable(T value) {return value == null? empty() : of(value); }} Copy the codeCopy the code
Therefore, when we are quite sure that the user object passed in is not empty, we can use the optional. of(user) method. If in doubt, use optional.ofnullable (user) to avoid null pointer exceptions in subsequent operations (map description).
Commonly used method
1. Get method
Public T get() {// If the value is null, an exception is thrown, Value if (value == null) {throw new NoSuchElementException("No value present"); } return value; } Duplicate codeCopy the code
2. IsPresent method
Public Boolean isPresent() {return value! Public Boolean isPresent() {return value! = null; } Duplicate codeCopy the code
Seeing this, I don’t know if there are any friends and I had the same doubts. So we have the null-calling method isPresent, and then we have the get method that gets the object. So that hole at the beginning, can I rewrite it as the following,
Private static String getUserAddr(Optional< user > user){// If user exists, If (user.ispresent ()){address = user.get().getAddress(); // wrap address as Optional object Optional< address > addressOptional = option.ofnullable (address); / / if the address is, then take the details address information if (addressOptional. IsPresent () {return addressOptional. The get () getDetails (); }else {return "Address info not filled in "; }}else{return "Address information is not filled in "; }} Copy the codeCopy the code
So it looks like the functionality is being implemented. However, leaving aside the fact that the code is not cleaner (it is more complex), it is trapped in a vicious cycle.
Because, if(user.ispresent ()){} and manually nulled if(user! =null){} is essentially indistinguishable. This is limited by the way we’ve been thinking about code.
So, let’s not call the isPresent method manually.
Not surprisingly, the isPresent method is intended to serve other Optional methods (such as the map method) and is not intended to be called manually. You’re going to see isPresent in a couple of subsequent methods.
3, ifPresent
// Pass in a consumable interface and consume only when the value exists. public void ifPresent(Consumer<? super T> consumer) { if (value ! = null) consumer.accept(value); } Duplicate codeCopy the code
Unlike the isPresent method, the ifPresent method is recommended.
If you can call it empty like this,
Optional<User> user = Optional.ofNullable(new User()); user.ifPresent(System.out::println); If (user.ispresent ()) {system.out.println (user.get()); } Duplicate codeCopy the code
OrElse and orElseGet
public T orElse(T other) { return value ! = null ? value : other; } public T orElseGet(Supplier<? extends T> other) { return value ! = null ? value : other.get(); } Duplicate codeCopy the code
Both methods are used to return a default value if the value does not exist. If the user object is null, the default value is returned.
@Test public void test1(){ User user = null; System. The out. Println (" orElse calls "); User user1 = Optional.ofNullable(user).orElse(createUser()); System. The out. Println (" orElseGet calls "); User user2 = Optional.ofNullable(user).orElseGet(() -> createUser()); } private User createUser() {private User createUser() {system.out.println ("createUser... ); return new User(); } // print the result orElse call createUser... CreateUser orElseGet call... Copy the codeCopy the code
When user is null, there is no difference between the two methods. Because you need to create a User object to return as the default.
However, when the user object is not null, let’s look at the comparison result,
@Test public void test2(){ User user = new User(); System. The out. Println (" orElse calls "); User user1 = Optional.ofNullable(user).orElse(createUser()); System. The out. Println (" orElseGet calls "); User user2 = Optional.ofNullable(user).orElseGet(() -> createUser()); } // print the result orElse call createUser... OrElseGet calls copy codeCopy the code
As you can see, when the user object is not null, orElse will still create the user object, but orElseGet will not.
Therefore, it is recommended to use orElseGet() when the orElse() method passes arguments that require object creation or time-consuming operations.
5, orElseThrow
When null, custom exceptions can be returned.
User user = null; Optional.ofNullable(user).orElseThrow(IllegalAccessError::new); Copy the codeCopy the code
If the user object is null, illegal access is thrown.
In this way, you can do some other processing for specific exceptions. Because we can control what kind of exceptions are thrown.
6, the map
public<U> Optional<U> map(Function<? super T, ? extends U> mapper) { Objects.requireNonNull(mapper); // See, map will call isPresent first to null. // Call isPresent if (! isPresent()) return empty(); else { return Optional.ofNullable(mapper.apply(value)); }} Copy the codeCopy the code
Map is similar to the Map method of Stream. Once we’re done, we’re still returning an Optional object, so we can do a chain call.
User user = new User(); String name = Optional. Of (user).map(user ::getName).orelse (" anonymous "); System.out.println(name); Copy the codeCopy the code
As above, take the name value of the User object. If name is empty, return a default value of “anonymous” (magic name).
Here, by calling the map method directly, there is no need to pre-null the User object. Because in the map method, isPresent is called to help us handle the case where user is null.
Here, head spinning fast friends, is not the beginning of the pit has been inspired.
Yeah, we can do Optional chain calls, map, orElse, etc. As follows,
Private static String getUserAddr1(Optional<User> User){return user.map((u)->u.getAddress())) Map (e -> LLDB details ()).map(e -> LLDB details ()).map(e -> LLDB details ()) } Duplicate codeCopy the code
Optional avoids all possible null Pointers. Because the value! The =null operation is already encapsulated. And Optional automatically wraps different types of values for us at different processing stages.
As in the above operation, the first map method wraps the User object value of type User, the second map wraps the Details value of type String, and orElse returns the final desired String.
7, flatMap
public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) { Objects.requireNonNull(mapper); if (! isPresent()) return empty(); else { return Objects.requireNonNull(mapper.apply(value)); }} Copy the codeCopy the code
At first glance, this method is no different from Map. In fact, the difference is the second generic of the mapper parameter passed in.
The second generic of map is? Extends U, flatMap The second generic is Optional.
So, the map method is wrapped up as Optional with the method option. ofNullable at the end. FlatMap, however, requires us to wrap Optional ourselves.
Let’s see how flatMap works.
@Test public void test3(){ User user = new User(); String name = Optional. Of (user).flatMap((u) -> this.getUsername (u)).orelse (" anonymous "); System.out.println(name); } // Wrap the user name as Optional<String> as the return value of the Function interface, FlatMap private Optional<String> getUserName(User User){return option.ofNullable (user.getName()); } Duplicate codeCopy the code
8, the filter
public Optional<T> filter(Predicate<? super T> predicate) { Objects.requireNonNull(predicate); if (! isPresent()) return this; else return predicate.test(value) ? this : empty(); } Duplicate codeCopy the code
If the criteria are met, the current Optional object itself is returned. If the criteria are met, an Optional object with a value of NULL is returned.
As follows, filter users with empty names.
User user = new User(); // Since user does not set name, OptionalUser Optional<User> optionalUser = option.of (User).filter((u) -> this.getUserName(u).isPresent()); NoSuchElementException optionalUser.get(); NoSuchElementException optionalUser.get(); Copy the codeCopy the code
Six, Stream API
First, what is a Stream?
Streams are similar to collections in Java. But collections hold data, whereas streams hold operations on data in collections or arrays.
It is called flow because it is like an assembly line. From a raw material to a usable finished product after n processes.
A stream operates on data in three steps: data source, intermediate operation, and termination operation.
The data source
The source of a stream can be an array, a collection, a generator method, and so on.
1. Use the default method in the Collection interface.
Default Stream<E> Stream() // returns a sequential Stream default Stream<E> parallelStream() // returns a parallelStream copy codeCopy the code
At this point, we can see why JDK8 introduced default methods.
Since the Collection parent defines these default methods, implementation classes under subinterfaces such as List and Set can generate a Stream in this way.
public class StreamTest { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("zhangzan"); list.add("lisi"); list.add("wangwu"); // Stream<String> Stream = list.stream(); // parallelStream <String> parallelStream = list.parallelstream (); ForEach (system.out ::println); }} Copy the codeCopy the code
2, Arrays static method stream()
Static <T> Stream<T> Stream (T[] arrayCopy the code
You can pass in arrays of various types and turn them into streams. As follows, pass in an array of strings.
String[] arr = {"abc","aa","ef"}; Stream<String> stream1 = Arrays.stream(arr); Copy the codeCopy the code
3, Stream interface of(), generate(), iterate() methods
Note that the of() method returns a finite stream, meaning it has a finite number of elements, the number of elements you pass in.
Generate () and iterate() are infinite streams, with an infinite number of elements.
The method of use is as follows,
//of Stream<Integer> stream2 = Stream.of(10, 20, 30, 40, 50); stream.forEach(System.out::println); Stream<Integer> generate = stream.generate (() -> new Random().nextint (100)); Stream<Integer> generate = stream.generate (() -> new Random().nextint (100)); // Iterate from 0, add 2 Stream<Integer> for each element as iterate = Stream. Iterate (0, x -> x + 2); Copy the codeCopy the code
IntStream, LongStream, DoubleStream of, range, rangeClosed
They are all used the same way, but in a straight wrapper.
In fact, the of() method also uses the arrays.stream () method underneath.
Take the IntStream class for example, and similarly,
IntStream intStream = IntStream.of(10, 20, 30); RangeStream = intstream. range(0, 10); IntStream rangeClosed = intstream. rangeClosed(0, 10); Copy the codeCopy the code
In the middle of operation
A stream can have zero or more intermediate operations, and each intermediate operation returns a new stream for the next operation to use.
1. Screening and slicing
Common ones include:
- filter
- limit
- skip
- distinct
2, mapping,
Mainly map, including:
- map
- mapToInt
- mapToLong
- mapToDouble
- flatMap
3, sorting,
- sorted()
- sorted(Comparator<? super T> comparator)
There are two methods for sorting, one of which takes no arguments and defaults to the natural order. One is parameterised and can specify a comparator.
@Test public void test4(){ String[] arr = {"abc","aa","ef"}; // Default ascending (dictionary ascending) stream.of (arr).sorted().foreach (system.out ::println); System.out.println("====="); Sorted ((s1,s2) -> s2.compareTo(s1)). ForEach (system.out ::println); } Duplicate codeCopy the code
Termination of operations
A stream will have only one termination operation. Stream’s source does not begin traversal until it encounters a termination operation. Note that after this, the stream is no longer usable.
1. Find and match
- AllMatch (Predicate P), passing in a Predicate function to check whether all elements match
- AnyMatch ((Predicate P)) checks to see if either element matches
- NoneMatch (Predicate P) checks if there are no matching elements, and returns true if none
- FindFirst (), returns the first element
- FindAny (), returns any element
- Count () returns the total number of elements in the stream
- Max (Comparator c) returns the largest element, sorted by the given rules
- Min (Comparator C) returns the smallest element after sorting according to the given rules
- ForEach (Consumer C), iterating through elements (iterating inside)
Because the above API is too simple, I will not do the example.
2, specification
A protocol is a reduce, which aggregates data together. I’m sure you’ve heard of Map-Reduce for Hadoop, and the idea is the same.
; Copy the code
3, collect
Collection operations that collect streams into lists, sets, maps, etc. In addition, the Collectors class provides many static methods for creating Collectors.
Here are a few commonly used ones. For details about the Collectors API, see the source code. It covers the maximum, minimum, counting, and grouping functions. .
@Test public void test6() { ArrayList<Employee> list = new ArrayList<>(); List. add(new Employee(" 三", 3000)); List. add(new Employee(" lI Si ", 5000)); List. add(new Employee(" 五", 4000)); List. add(new Employee(" zhao 6 ", 4500)); List.stream ().map(Employee::getName).collect(Collectors. ToList ()).foreach (system.out ::println); / / the average salary of all employees Double business = list. The stream () collect (Collectors. AveragingDouble (Employee: : getSalary)); System.out.println(average); } Duplicate codeCopy the code
New API for date and time
The time API prior to JDK8 had thread-safety issues and was poorly designed. As a result, an API has been redesigned in JDK8.
Here is an example of thread insecurity.
@Test public void test1() throws Exception{ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); ExecutorService executorService = Executors.newFixedThreadPool(10); List<Future<Date>> list = new ArrayList<>(); for (int i = 0; i < 10; i++) { Future<Date> future = executorService.submit(() -> sdf.parse("20200905")); list.add(future); } for (Future<Date> future : list) { System.out.println(future.get()); }} Copy the codeCopy the code
Run multiple times, there will be an error in Java. Lang. A NumberFormatException.
Next, we’ll take a look at the new time API and rewrite the above application.
LocalDate, LocalTime, LocalDateTime
They are both immutable classes and have similar usage. Take LocalDate as an example.
Create a time object
-
Now, static method that creates an object based on the current time
-
Of, a static method that creates an object based on the specified date and time
-
Parse, static method that specifies a date through a string
LocalDate localDate1 = LocalDate.now(); System.out.println(localDate1); //2020-09-05 LocalDate localDate2 = LocalDate.of(2020, 9, 5); System.out.println(localDate2); //2020-09-05 LocalDate localDate3 = LocalDate.parse(“2020-09-05”); System.out.println(localDate3); //2020-09-05 copy code
2. Get year, month, day and week
-
GetYear: Gets the year
-
GetMonth, gets the month and returns an enumeration of the month values
-
GetMonthValue, get the number of months (1-12)
-
GetDayOfYear, get the number of days in a year (1-366)
-
GetDayOfMonth, get the number of days in a month (1-31)
-
GetDayOfWeek, which gets the day of the week and returns an enumerated value
LocalDate currentDate = LocalDate.now(); System.out.println(currentDate.getYear()); //2020 System.out.println(currentDate.getMonth()); // SEPTEMBER System.out.println(currentDate.getMonthValue()); //9 System.out.println(currentDate.getDayOfYear()); //249 System.out.println(currentDate.getDayOfMonth()); //5 System.out.println(currentDate.getDayOfWeek()); // SATURDAY copies the code
3, date comparison, before and after or equal
- IsBefore, whether the first date isBefore the second date
- IsAfter, is it after
- Equals, whether the dates are the same
- IsLeapYear, whether it is a leap year
They all return a Boolean value.
LocalDate date1 = LocalDate.of(2020, 9, 5); LocalDate date2 = LocalDate.of(2020, 9, 6); System.out.println(date1.isBefore(date2)); //true System.out.println(date1.isAfter(date2)); //false System.out.println(date1.equals(date2)); //false System.out.println(date1.isLeapYear()); //true copies the codeCopy the code
4. Dates plus or minus
- PlusDays, add a few days
- PlusWeeks, plus a couple of weeks
- PlusMonths, plusMonths
- PlusYears, plusYears
And the same thing with subtraction,
LocalDate nowDate = LocalDate.now(); System.out.println(nowDate); //2020-09-05 System.out.println(nowDate.plusDays(1)); //2020-09-06 System.out.println(nowDate.plusWeeks(1)); //2020-09-12 System.out.println(nowDate.plusMonths(1)); //2020-10-05 System.out.println(nowDate.plusYears(1)); // copy the codeCopy the code
Timestamp Instant
Instant represents a timestamp computed from 00:00 00:00 January 1, 1970 in the UTC time zone.
Instant now = Instant.now(); System.out.println(now.toString()); / / the T14:2020-09-05 11:07. 074 z System. Out. The println (now. ToEpochMilli ()); // number of milliseconds, 1599315067074 copy codeCopy the code
Time Duration
The value can be a time range between LocalDateTime and Instant. The value is created between.
LocalDateTime today = LocalDateTime.now(); // LocalDateTime tomorrow = today.plusdays (1); // LocalDateTime tomorrow = today.plusdays (1); Duration Duration = Duration. Between (today, tomorrow); System.out.println(duration.todays ()); system.out.println (duration.todays ()); // Total number of days, 1 system.out.println (duration.tohours ()); // hour, 24 system.out.println (duration.tominutes ()); // hour, 24 system.out.println (duration.tominutes ()); // min, 1440 system.out.println (duration.getseconds ()); // SEC, 86400 system.out.println (duration.tomillis ()); // SEC, 86400 system.out.println (duration.tomillis ()); // milliseconds, 86400000 system.out.println (duration.tonanos ()); // milliseconds, 86400000 system.out.println (duration.tonanos ()); // nanosecond, 86400000000000 copy codeCopy the code
The date Period of Period
Duration and time, but Period is only accurate to year, month and day.
There are two ways to create Duration.
LocalDate today = LocalDate.now(); // today LocalDate date = localdate.of (2020,10,1); Period Period = Period. Between (today, date); System.out.println(period); Period of = Period. Of (2020, 9, 6); System.out.println(of); System.out.printf(" %d %d month %d day ", period.getYears(),period.getMonths(),period.getDays()); Copy the codeCopy the code
Time zone ZoneId
ZoneId indicates different time zones.
-
GetAvailableZoneIds (), gets all the time zone information, about 40 + time zones
-
Of (id) : obtains the corresponding ZoneId object according to the time ZoneId
-
SystemDefault, to get the current time zone
Set availableZoneIds = ZoneId.getAvailableZoneIds(); availableZoneIds.forEach(System.out::println); ZoneId of = zoneid. of(“Asia/Shanghai”); System.out.println(of); system.out.println (of); System.out.println(ZoneId.systemDefault()); // The current time zone is Asia/Shanghai
Date and time formatting
JDK1.8 provides the thread-safe date formatter class DateTimeFormatter.
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); // 1. Convert date and time to a string. String format = dtf.format(localDatetime.now ()); System.out.println(format); // 2020-09-05 23:02:02 String format1 = LocalDateTime.now().format(dtf); // The format method of the DateTimeFormatter class is called system.out.println (format1); // 2020-09-05 23:02:02 // 2. Datetimeformatter.iso_local_date_time, datetimeformatter.iso_local_date_time, datetimeformatter.iso_local_date_time, LocalDateTime parse = localDatetime. parse("2020-09-05T00:00:00"); System.out.println(parse); Parse1 = localDatetime. parse("2020-09-05 00:00:00", DTF); System.out.println(parse1); // 2020-09-05t00:00 copy codeCopy the code
Change to thread-safe class
Next, you can rewrite the classes that are unsafe for the upper thread into the new time-based API.
@test public void test8() throws Exception{// SimpleDateFormat changes to DateTimeFormatter DateTimeFormatter DTF = DateTimeFormatter.ofPattern("yyyyMMdd"); ExecutorService executorService = Executors.newFixedThreadPool(10); LocalDate List<Future<LocalDate>> List = new ArrayList<>(); for (int i = 0; i < 10; Parse (" executorService ", DTF) Future< executorService > Future = executorService.submit(() -> LocalDate.parse("20200905",dtf)); list.add(future); } for (Future<LocalDate> future : list) { System.out.println(future.get()); }} Copy the codeCopy the code
Pick to:
JDK15 is coming and you don’t know the new features of JDK8 yet
juejin.im
] (link.zhihu.com/?target=htt…).