preface
This article is about the use of some new syntax features in JDK1.8 in Java. It is mainly about Lambda, Stream and LocalDate.
Lambda
Lambda is introduced
Lambda expression is an anonymous function, named after the Lambda calculus in mathematics and directly corresponds to its Lambda abstraction, which is an anonymous function without a function name.
Structure of a Lambda expression
-
A Lambda expression can have zero or more arguments
-
The types of parameters can be either explicitly declared or inferred from context. For example :(int a) has the same effect as (a)
-
All arguments must be enclosed in parentheses, separated by commas. For example :(a, b) or (int a, int b) or (String a, int b, float c)
-
Empty parentheses indicate that the parameter set is empty. For example :() -> 42
-
The parentheses () can be omitted when there is only one argument and its type is derivable. For example, a -> return A *a
-
The body of a Lambda expression can contain zero or more statements
-
If the body of a Lambda expression has only one statement, the curly braces {} may be omitted. The return type of the anonymous function is the same as that of the principal expression
-
If the body of a Lambda expression contains more than one statement, the expression must be enclosed in curly braces {} (to form a code block). The return type of the anonymous function is the same as the return type of the code block, or null if there is no return
Use of Lambda expressions
Let’s start with a simple example to see Lambda in action.
For example, the traditional way to traverse a Map is as follows:
Map<String, String> map = new HashMap<>(); map.put("a", "a"); map.put("b", "b"); map.put("c", "c"); map.put("d", "d"); System.out.println("map normal traversal :"); For (String key: map.keyset ()) {system.out.println ("k=" + key + ", v=" + map.get(key)); }Copy the code
Use Lambda for traversal:
System.out.println("map ramda expression traversal :"); Map. ForEach ((k, v) - > {System. Out. Println (" k = "+ k +", v = "+ v); });Copy the code
The same is true for lists, but lists can also be traversed by the double colon operator:
List<String> list = new ArrayList<String>(); list.add("a"); list.add("bb"); list.add("ccc"); list.add("dddd"); System.out.println("list ramda expression traversal :"); list.forEach(v -> { System.out.println(v); }); System.out.println("list double colon operator traversal :"); list.forEach(System.out::println);Copy the code
Output result:
Map Common traversal: k=a, v=a k=b, v=b K = C, v=c K =d, v=d Map Traversal: K =a, V =a K =b, v=b k= C, v=c k=d, v=d list Traversal: A bb CCC DDDD list Double colon operator traversal: a bb CCC DDDDCopy the code
In addition to Lambda being used in for loop traversal, it can also replace anonymous inner classes. For example, the following thread creation example:
R1 = new Runnable() {@override public void run() {system.out.println (" Runnable! ); }}; // Create Runnable r2 = ()-> system.out.println (" create Runnable r2!") );Copy the code
Note: When Lambda expressions are used in this example, the compiler automatically deduces that they are assigned to the Runnable interface based on the thread class’s constructor signature Runnable r {}.
Lambda Expressions vs. Anonymous Classes One big difference between using anonymous classes and Lambda expressions is the use of keywords. For anonymous classes, the keyword this is read as an anonymous class, and for Lambda expressions, the keyword this is read as the external class that writes the Lambda.
Considerations for using Lambda expressions
Lambda simplifies code writing, but it also reduces readability.
Stream
The Stream is introduced
Stream provides a high-level abstraction of Java collection operations and expressions in an intuitive manner similar to querying data from a database with SQL statements. The Stream API can greatly improve the productivity of Java programmers, allowing programmers to write efficient, clean, and concise code. This style treats the collection of elements to be processed as a stream that travels through a pipe and can be processed at the nodes of the pipe, such as filtering, sorting, aggregating, and so on.
The Stream features:
-
Not a data structure: it has no internal storage, it just grabs data from a source (data structure, array, Generator function, IO channel) with an operation pipe. It also never modifies the data of the underlying data structure that it encapsulates. For example, the filter operation on a Stream produces a new Stream without the filtered elements, rather than removing those elements from the source.
-
Index access is not supported: it is easy to generate arrays or lists.
-
Lazy: Many Stream operations are deferred until it figures out how much data it will eventually need to start. The Intermediate operation is always inerted.
-
Parallel capability. When a Stream is parallelized, there is no need to write multithreaded code; all operations on it are automatically done in parallel.
-
It can be infinite: collections have fixed sizes, streams do not. Short-circuiting operations like Limit (n) and findFirst() can evaluate an infinite Stream and complete quickly.
-
** Note: All Stream operations must take lambda expressions as arguments. **
Stream Operation type:
-
Intermediate: A stream can be followed by zero or more Intermediate operations. The main purpose is to open the stream, do some degree of data mapping/filtering, and then return a new stream to be used by the next operation. These operations are lazy, meaning that they are called without actually starting the flow.
-
Terminal: A stream can have only one Terminal operation. After this operation is performed, the stream is used as light and cannot be operated again. So this must be the last operation of the stream. The execution of the Terminal operation will actually start the stream traversal and will produce a result, or side effect.
The Stream to use
Let’s continue with a simple example here. In the development process, we sometimes need to filter some data. If we use the traditional way, we need to filter this batch of data, which will be tedious. If we use the Steam stream method, it can be very convenient to process.
First, filter in the usual way:
List<String> List = array.aslist ("张三", "张三", "张三", "张三", "张三"); System.out.println(" before filtering :" + list); List<String> result = new ArrayList<>(); for (String str : list) { if (!" .equals(STR)) {result.add(STR); }} system.out. println(" filter :" + result);Copy the code
Filter using Steam:
List<String> result2 = list.stream().filter(str -> !" Li si ". The equals (STR)). Collect (Collectors. ToList ()); System.out.println("stream after filter :" + result2);Copy the code
Output result:
After filtering :[Zhang SAN, Wang Wu, Xuwujing] after filtering :[Zhang SAN, Wang Wu, Xuwujing]Copy the code
Is it very simple and convenient? There are more ways to use Stream, and filter is just one of them. So let’s learn about them here.
1. Construct a Stream
Stream stream = Stream.of("a", "b", "c"); String[] strArray = new String[] { "a", "b", "c" }; stream = Stream.of(strArray); stream = Arrays.stream(strArray); List<String> list = Arrays.asList(strArray); stream = list.stream();
Copy the code
2.Stream conversion between streams
Note that a Stream can only be used once, and this code is repeated several times for brevity, thus raising the Stream has already been operated upon or closed exception.
try { Stream<String> stream2 = Stream.of("a", "b", "c"); StrArray1 = stream2.toarray (String[]::new); // Convert to Collection List<String> list1 = stream2.collect(Collectors. ToList ()); List<String> list2 = stream2.collect(Collectors.toCollection(ArrayList::new)); Set set1 = stream2.collect(Collectors.toSet()); Stack stack1 = stream2.collect(Collectors.toCollection(Stack::new)); STR = stream.collect(Collectors. Joining ()).tostring (); } catch (Exception e) { e.printStackTrace(); }Copy the code
3.Stream Map usage of streams
The map method is used to map each element to the corresponding result, one-to-one.
Example 1: Convert uppercase
List<String> list3 = Arrays.asList("zhangSan", "liSi", "wangWu"); System.out.println(" data before conversion :" + list3); List<String> list4 = list3.stream().map(String::toUpperCase).collect(Collectors.toList()); System.out.println(" converted data :" + list4); [ZHANGSAN, LISI,WANGWU]Copy the code
Example 2: Converting data types
List<String> list31 = Arrays.asList("1", "2", "3"); System.out.println(" data before conversion :" + list31); List<Integer> list41 = list31.stream().map(Integer::valueOf).collect(Collectors.toList()); System.out.println(" converted data :" + list41); / / [1, 2, 3]Copy the code
Example 3: Get the square
List<Integer> list5 = Arrays.asList(new Integer[] { 1, 2, 3, 4, 5 }); List<Integer> list6 = list5.stream().map(n -> n * n).collect(Collectors.toList()); System.out.println(" square data :" + list6); // [1, 4, 9, 16, 25]Copy the code
4.Stream Indicates the filter of the Stream
The filter method is used to filter out elements by the set criteria.
Example 2: Get the if/else value with findAny
List<String> List = array.aslist ("张三", "张三", "张三", "张三", "张三"); String result3 = list.stream().filter(STR -> "equals ".equals(STR)).findany ().orelse (" not found! ); String result4 = list.stream().filter(STR -> "equals ".equals(STR)).findany ().orelse (" not found! ); System.out.println("stream after 2:" + result3); System.out.println("stream after 3:" + result4); //stream is not found! //stream is not found!Copy the code
Example three: calculate and with mapToInt
List<User> lists = new ArrayList<User>(); Lists. Add (new User(6, "zhang SAN ")); Lists. Add (new User(2, "lisi ")); Lists. Add (new User(3, "king ")); Lists. Add (new User(1, "三")); Int sum = lists.stream().filter(u -> "equals" (u.get_name ())).mapToint (u -> u.get_name ()).sum(); System.out.println(" + sum "); / / 7Copy the code
5. FlatMap is used for streams
The flatMap method is used to map each element to the corresponding result, one-to-many.
Example: Get a word from a sentence
String worlds = "The way of the future"; List<String> list7 = new ArrayList<>(); list7.add(worlds); List<String> list8 = list7.stream().flatMap(str -> Stream.of(str.split(" "))) .filter(world -> world.length() > 0).collect(Collectors.toList()); System. The out. Println (" words: "); list8.forEach(System.out::println); // words: // The way // of // The // futureCopy the code
6.Stream limit usage
The limit method is used to get a specified number of streams.
Example 1: Get the first n items of data
Random rd = new Random(); System.out.println(" fetch first three data :"); rd.ints().limit(3).forEach(System.out::println); // Get the first three data: // 1167267754 // -1164558977 // 1977868798Copy the code
Example 2: Use with SKIP to get the required data
Skip means to throw away the first n elements.
List<User> list9 = new ArrayList<User>(); for (int i = 1; i < 4; i++) { User user = new User(i, "pancm" + i); list9.add(user); } system.out. println(" extract from previous data :"); // get the first 3 items, but discard the first 2 items, List<String> list10 = 2<= I <3 (I is the number of subscripts list9.stream().map(User::getName).limit(3).skip(2).collect(Collectors.toList()); System.out.println(" truncated data :" + list10); // name :pancm1 // name :pancm3 // name :pancm3 //Copy the code
Note: The getName method in the User entity class prints the name.
7.Stream Uses sort for streams
The sorted method is used for ascending sorting of convection.
Example 1: Sort values randomly
Random rd2 = new Random(); System.out.println(" take the first three values and sort them :"); rd2.ints().limit(3).sorted().forEach(System.out::println); // Take the first three data and sort them: // -2043456377 // -1778595703 // 1013369565Copy the code
Example 2: Optimize sort
Tips: Getting first is more efficient in sorting!
List<User> list11 = list9.stream().sorted((u1, u2) -> u1.getName().compareTo(u2.getName())).limit(3) .collect(Collectors.toList()); System.out.println(" sort data :" + list11); List<User> list12 = list9.stream().limit(3).sorted((u1, u2) -> u1.getName().compareTo(u2.getName())) .collect(Collectors.toList()); System.out.println(" + list12); / / after the sorting data: [{" id ": 1," name ":" pancm1 "}, {" id ": 2," name ":" pancm2 "}, {" id ": 3," name ":" pancm3} "] / / optimization after sorting data: [{" id ": 1," name ":" pancm1 "}, {" id ": 2," name ":" pancm2 "}, {" id ": 3," name ":" pancm3} "]Copy the code
8. Peek use of Stream
Peek performs an operation on each element and returns a new Stream
Example: dual operation
System. The out. Println (" peek use: "); Stream of (" one ", "two", "three", "four"). The filter (e - > e.l ength () > 3). The peek (e - > System. Out. The println (" before the conversion: "+ e)).map(String::toUpperCase).peek(e -> system.out.println (" after transformation:" + e)).collect(Collectors. // Before conversion: three // after conversion: three // before conversion: four // after conversion: fourCopy the code
9. parallel use of streams
ParallelStream is an alternative to stream parallel processing.
Example: Get the number of empty strings
List<String> strings = Arrays.asList("a", "", "c", "", "e","", " "); Long count = strings.parallelstream ().filter(string -> string.isEmpty()).count(); System.out.println(" number of empty strings :"+count);Copy the code
10.Stream Specifies the Max /min/distinct usage of streams
Example 1: Get the maximum and minimum values
List<String> list13 = Arrays.asList("zhangsan","lisi","wangwu","xuwujing"); int maxLines = list13.stream().mapToInt(String::length).max().getAsInt(); int minLines = list13.stream().mapToInt(String::length).min().getAsInt(); Println (" maxLines+", "minLines +"); // Maximum character length :8, minimum character length :4Copy the code
Example 2: Get the de-weighted data
String lines = "good good study day day up"; List<String> list14 = new ArrayList<String>(); list14.add(lines); List<String> words = list14.stream().flatMap(line -> Stream.of(line.split(" "))).filter(word -> word.length() > 0) .map(String::toLowerCase).distinct().sorted().collect(Collectors.toList()); System.out.println(" to repeat after :" + words); // repeat after :[day, good, study, up]Copy the code
11.Stream Matches the Stream
-
AllMatch: Stream returns true if all elements match;
-
AnyMatch: Stream returns true as long as one element of the Stream matches;
-
Return true if none of the elements in noneMatch: Stream match.
Example: Data match
boolean all = lists.stream().allMatch(u -> u.getId() > 3); System.out.println(" is all greater than 3:" + all); boolean any = lists.stream().anyMatch(u -> u.getId() > 3); System.out.println(" If there is one greater than 3:" + any); boolean none = lists.stream().noneMatch(u -> u.getId() > 3); System.out.println(" is there none greater than 3 :" + none); // Whether all of them are greater than 3:false // Whether all of them are greater than 3:true // Whether none of them are greater than 3:falseCopy the code
12.Stream Reduce usage of streams
Reduce is mainly used to combine Stream elements for operation.
Example 1: String concatenation
String concat = Stream.of("A", "B", "C", "D").reduce("", String::concat); System.out.println(" string concatenation :" + concat);Copy the code
Example 2: Get the minimum
Double minValue = stream. of(-4.0, 1.0, 3.0, -2.0).reduce(double.MAX_VALUE, double ::min); System.out.println(" min :" + minValue); // Minimum value :-4.0Copy the code
Example 3: Summation
Int sumValue = stream.of (1, 2, 3, 4).reduce(Integer::sum).get(); // Sum = stream.of (1, 2, 3, 4).reduce(Integer::sum).get(); System.out.println(" sum with or without starting value :" + sumValue); SumValue = stream.of (1, 2, 3, 4).reduce(1, Integer::sum); System.out.println(" sum with starting value :" + sumValue); // Sum with or without starting value :10 // Sum with starting value :11Copy the code
Example 4: Filter splicing
concat = Stream.of("a", "B", "c", "D", "e", "F").filter(x -> x.compareTo("Z") > 0).reduce("", String::concat); System.out.println(" filter and string concatenation :" + concat); // Filter and string concatenation :aceCopy the code
13. I iterate the Stream
Iterate is similar to reduce in that it accepts a seed value and an UnaryOperator (for example, f). The seed value then becomes the first element of the Stream, f(seed) the second, f(f(seed) the third, and so on. The pipe must have a limit operation for iterate to limit the Stream size.
Example: Generate an arithmetic queue
System.out.println(" generate an arithmetic queue from 2 :"); Stream.iterate(2, n -> n + 2).limit(5).forEach(x -> System.out.print(x + " ")); // Create an arithmetic queue starting from 2: // 2 4 6 8 10Copy the code
14.Stream Supplier uses the Stream
You can customize the flow evaluation rules by implementing the Supplier class methods.
Example: Obtain two user information randomly
System.out.println(" Customize a stream to compute output :"); Stream.generate(new UserSupplier()).limit(2).forEach(u -> System.out.println(u.getId() + ", " + u.getName())); First: / / / / a custom flow to calculate output: / / 10 and 11 pancm7 / /, pancm6 / / second: / / custom a flow to calculate output: / / 10, pancm4 / / 11, pancm2 / / for the third time: //10, pancm8class UserSupplier implements Supplier<User> {private int index = 10; //11, pancm8class UserSupplier implements Supplier<User> {private int index = 10; private Random random = new Random(); @Override public User get() { return new User(index++, "pancm" + random.nextInt(10)); }}Copy the code
15. The Stream flow groupingBy/partitioningBy use
-
GroupingBy: sort groups.
-
PartitioningBy: Sort partitions.
Example 1: Group sort
System.out.println(" Sort by id :"); Map<Integer, List<User>> personGroups = Stream.generate(new UserSupplier2()).limit(5) .collect(Collectors.groupingBy(User::getId)); Iterator it = personGroups.entrySet().iterator(); while (it.hasNext()) { Map.Entry<Integer, List<User>> persons = (Map.Entry) it.next(); System.out.println("id " + persons.getKey() + " = " + persons.getValue()); } // Group sort by id: // id 10 = [{"id":10,"name":"pancm1"}] // id 11 = [{"id":11,"name":"pancm3"}, {"id":11,"name":"pancm6"}, {"id":11,"name":"pancm4"}, {"id":11,"name":"pancm7"}] class UserSupplier2 implements Supplier<User> { private int index = 10; private Random random = new Random(); @Override public User get() { return new User(index % 2 == 0 ? index++ : index, "pancm" + random.nextInt(10)); }}Copy the code
Example 2: Partition sort
System.out.println(" sort by age :"); Map<Boolean, List<User>> children = Stream.generate(new UserSupplier3()).limit(5) .collect(Collectors.partitioningBy(p -> p.getId() < 18)); System.out.println(" children: "+ children. Get (true)); System.out.println(" adult: "+ children. Get (false)); / / partition sorting through the ages: / / kid: [{" id ": 16," name ":" pancm7 "}, {" id ": 17," name ":" pancm2} "] / / adults: [{"id":18,"name":"pancm4"}, {"id":19,"name":"pancm9"}, {"id":20,"name":"pancm6"}] class UserSupplier3 implements Supplier<User> { private int index = 16; private Random random = new Random(); @Override public User get() { return new User(index++, "pancm" + random.nextInt(10)); }}Copy the code
16.Stream Specifies the summaryStatistics of a Stream
IntSummaryStatistics State object used to collect statistics such as Count, min, Max, sum, and Average.
Example: Get maximum, minimum, sum, and average.
List<Integer> numbers = Arrays.asList(1, 5, 7, 3, 9); IntSummaryStatistics stats = numbers.stream().mapToInt((x) -> x).summaryStatistics(); System.out.println(" maximum number in list: "+ stats.getmax ()); System.out.println(" minimum number in list: "+ stats.getmin ()); System.out.println(" sum: "+ stats.getsum ()); System.out.println(" average: "+ stats.getaverage ()); // Maximum number in the list: 9 // Minimum number in the list: 1 // Sum of all numbers: 25 // average: 5.0Copy the code
There are many ways to use a Stream in JDK1.8. For more information, see the JDK1.8 API documentation.
LocalDateTime
introduce
In addition to lambda expressions and streams, JDK1.8 has a new date and time API. Prior to JDK1.8, the way Java handled dates, calendars, and times was criticized by the community. The mutable type of java.util.date and the non-thread-safe nature of SimpleDateFormat limited its use. Hence the java.time package, in which all classes are immutable and thread-safe.
The key class
-
Instant: indicates the Instant time.
-
LocalDate: indicates the LocalDate in the format yyyy-mm-dd, excluding the specific time.
-
LocalTime: indicates the LocalTime, excluding the date. Format YYYY-MM-DD HH: MM: ss.sss.
-
LocalDateTime: Combines date and time, but does not contain time difference or time zone information.
-
ZonedDateTime: The most complete date time, including the time zone and the time difference from UTC or Greenwich.
use
1. Obtain the current date and time
Get the current time with the static factory method now().
LocalDate nowDate = localdate.now (); LocalDate nowDate = localdate.now (); LocalDateTime nowDateTime = localDatetime.now (); // LocalDateTime nowDateTime = localDatetime.now (); System.out.println(" current time :"+nowDate); System.out.println(" current time :"+nowDateTime); // Current time :2018-12-19 // Current time :2018-12-19T15:24:35.822Copy the code
2. Obtain the current year, month, day, hour, minute, second
After obtaining the time, get directly obtains the time, minute and second of year, month and day.
LDT = localDatetime.now (); LDT = localDatetime.now (); System.out.println(" ldt.getYear() "); //2018 system.out. println(" current year :"+ ldt.getDayofYear ()); //172 system.out.println (" current month :"+ldt.getMonthValue()); //172 system.out.println (" current month :"+ldt.getMonthValue()); System.out.println(" current :"+ ldt.gethour ()); System.out.println(" ldt.getminute () "); System.out.println(" current time :"+ldt.toString()); // Current year :2018 // Current year days :353 // Current month :12 // Current time :15 // Current minute :24 // Current time :2018-12-19T15:24:35.833Copy the code
3. Format time
Time formatting requires the DateTimeFormatter class.
LocalDateTime ldt = LocalDateTime.now(); System. Out. Println (" formatting time: "+ LDT. The format (DateTimeFormatter. OfPattern (" MM - dd yyyy - HH: MM: ss. The SSS"))); // Format time :2018-12-19 15:37:47.119Copy the code
4. Time increases and decreases
Add/subtract hours/seconds at the specified time.
LocalDateTime ldt = LocalDateTime.now(); System.out.println(" 时间 时间:"+ ldt.plusdays (5)); System. The out. Println (" 5 days before the time and format: "+ LDT. MinusDays (5). The format (DateTimeFormatter. OfPattern (" yyyy - MM - dd"))); / / the 2018-06-16 System. Out. Println (" one month before the time: "+ ldt2. MinusMonths (1). The format (DateTimeFormatter. OfPattern (" yyyyMM"))); Println (" + ldt2.plusmonths (1)); //2018-06-16 system.out.println (" + ldt2.plusmonths (1)); //2018-06-16 system.out.println (" withYear(2099) + ldt.withyear (2099)); //2099-06-21T15:07:39.506 // Last 5 days time :2018-12-24T15:50:37.508 // First 5 days time and format :2018-12-14 // Last month time :201712 // 2018-02-04T09:19:29.499 // Specify the current time of 2099 :2099-12-19T15:50:37.508Copy the code
5. Create a specified time
Created by specifying a year, month and day.
LocalDate ld3=LocalDate.of(2017, Month.NOVEMBER, 17); LocalDate ld4=LocalDate.of(2018, 02, 11);
Copy the code
6. Time difference comparison
Compare the year, month, day, hour, minute, second.
Example 1: Specific difference in year month day
LocalDate ld=LocalDate.parse("2017-11-17"); LocalDate ld2=LocalDate.parse("2018-01-05"); Period p=Period.between(ld, ld2); System. The out. Println (" differ in: "+ p.g etYears () +" vary month: "+ p.g etMonths () +" vary day: "+ p.g etDays ()); // Year difference: 0 Month difference :1 Day difference :19Copy the code
Note: the month here is not satisfied with a year, days are not satisfied with a month. The actual difference here is 19 Days of January, which is 49 days.
Example 2: Time of total difference
ChronoUnit A standard set of date cycle units.
LocalDate startDate = LocalDate.of(2017, 11, 17); LocalDate endDate = LocalDate.of(2018, 01, 05); System. The out. Println (" differ in: "+ ChronoUnit. Have between (startDate, endDate)); System.out.println(" chronounit.days. between(startDate, endDate)); // Month difference :1 // Days difference between two days: 49Copy the code
Note :ChronoUnit can also calculate time difference minutes and seconds.
Example 3: Accuracy time difference
Duration This class models the amount or quantity of time in seconds and nanoseconds.
Instant inst1 = Instant.now(); System.out.println(" current timestamp: "+ inst1); Instant inst2 = inst1.plus(Duration.ofSeconds(10)); System.out.println(" time after increment: "+ inst2); System.out.println(" duration.between (inst1, inst2).tomillis ()); System.out.println(" phase milliseconds: "+ duration.between (inst1, inst2).getseconds ()); // Current timestamp: 2018-12-19T08:14:21.675z // Added time: 2018-12-19T08:14:31.675z // Difference ms: 10000 // phase ms: 10Copy the code
Example 4: Time size comparison
LocalDateTime ldt4 = LocalDateTime.now(); LocalDateTime ldt5 = ldt4.plusMinutes(10); System.out.println(" is the current time greater than :"+ ldt4.isafter (ldt5)); System.out.println(" is the current time less than "+ ldt4.isbefore (ldt5)); // false // trueCopy the code
7. Time zone time calculation
Get the time in another time zone.
Example 1: Get calculations from the Clock Clock class
The Clock Clock class is used to get the current timestamp, or date-time information for the current time zone.
Clock clock = Clock.systemUTC(); System.out.println(" current timestamp: "+ clock.millis()); Clock clock2 = Clock.system(ZoneId.of("Asia/Shanghai")); System.out.println(" clock2.millis() "); Clock clock3 = Clock.system(ZoneId.of("America/New_York")); Println (" clock3.millis() +clock3.millis()); // Current time stamp :1545209277657 // Shanghai, Asia time stamp :1545209277657 // New York, USA time stamp :1545209277658Copy the code
Example 2: Through the ZonedDateTime class and ZoneId
ZoneId zoneId= ZoneId.of("America/New_York"); ZonedDateTime dateTime=ZonedDateTime.now(zoneId); System. Out. Println (" at this point of time in New York, USA: "+ dateTime. The format (DateTimeFormatter. OfPattern (" MM - dd yyyy - HH: MM: ss. The SSS"))); System.out.println(" dateTime + dateTime "); 2018-12-19T03:52:22.494-05:00[America/New_York] 2018-12-19T03:52:22.494-05:00Copy the code
Java 8 Datetime API Summary:
-
Javax.time. ZoneId is provided to get the time zone.
-
LocalDate and LocalTime classes are provided.
-
All Date and time apis in Java 8 are immutable classes and thread-safe, while java.util.Date and SimpleDateFormat in the existing Date and Calendar apis are thread-safe.
-
The main package is java.time, which contains classes that represent dates, times, and time intervals. There are two subpackages java.time.format for formatting and java.time.temporal for lower-level operations.
-
A time zone represents the standard time commonly used in a region of the earth. Each time zone has a code name, usually in the form of Asia/Tokyo, plus the time difference from Greenwich or UTC. For example, the time difference in Tokyo is +09:00.
-
The OffsetDateTime class actually combines the LocalDateTime class with the ZoneOffset class. Represents complete date (year, month, day) and time (hour, minute, second, nanosecond) information that contains the time difference from Greenwich or UTC.
-
The DateTimeFormatter class is used to format and parse time. Unlike SimpleDateFormat, this class is immutable and thread-safe, allowing static constants to be assigned as needed. The DateTimeFormatter class provides a number of built-in formatting tools, as well as allowing you to customize. On the conversion side, parse() is also provided to parse a string into a date, throwing a DateTimeParseException if parsing fails. The DateTimeFormatter class also has format() for formatting dates and throws a DateTimeException if an error occurs.
-
In addition, the date formats “MMM d YYYY” and “MMM DD YYYY” have some subtle differences. The first format can parse “Jan 2 2014” and “Jan 14 2014”, while the second one will throw an exception when parsing “Jan 2 2014”. Because the second format requires that the day be two digits. If you want to correct it, you have to add zeros in front of the date if it has only one digit, so “Jan 2 2014” should be written as “Jan 02 2014”.