Java 8 New Features Guide Best

Java 8 New Features Guide Best

With the popularity of Java 8 is getting higher and higher, many people have mentioned the interview on Java 8 is also very frequently asked knowledge points. Requirements and should you need, I'm going to make a summary of this part of knowledge. It originally planned to own summary, see later there is an associated warehouse, the address on Github: https://github.com/winterbe/java8-tutorial. The warehouse is in English, I had it translated and add and modify a part, took two weeks off work things out, here is the text of.

table of Contents

接口的默认方法(Default Methods for Interfaces)

Lambda表达式(Lambda expressions)

函数式接口(Functional Interfaces)

方法和构造函数引用(Method and Constructor References)

Lamda 表达式作用域(Lambda Scopes)

    访问局部变量

    访问字段和静态变量

    访问默认接口方法

内置函数式接口(Built-in Functional Interfaces)

    Predicates

    Functions

    Suppliers

    Consumers

    Comparators

Optionals

Streams(流)

    Filter(过滤)

    Sorted(排序)

    Map(映射)

    Match(匹配)

    Count(计数)

    Reduce(规约)

Parallel Streams(并行流)

    Sequential Sort(串行排序)

    Parallel Sort(并行排序)

Maps

Data API(日期相关API)

    Clock

    Timezones(时区)

    LocalTime(本地时间)

    LocalDate(本地日期)

    LocalDateTime(本地日期时间)

Annotations(注解)

Whete to go from here?

Java 8 Tutorial

Welcome to my introduction to Java 8's. This tutorial will walk you through all the new language features. On the basis of the short code examples, you will learn how to use the default interface methods, lambda expressions, and repeatable method references notes. At the end of this article, you will be familiar with the latest API changes, such as flow, function interface (Functional Interfaces), Map classes extensions and new Date API. No large segment of boring text, only a bunch of commented code fragments.
The default interface methods (Default Methods for Interfaces)

Java 8 will enable us to add a non-abstract methods to the interface by using the default keyword. This feature is also known as a virtual extension methods.

The first example:

interface Formula{


    double calculate(int a);


    default double sqrt(int a) {

        return Math.sqrt(a);

    }


}

Formula interface Interface calculating equation defines the abstract methods in addition to the default method sqrt. Class that implements the interface need only implement the abstract methods calculate. The default method sqrt can be used directly. Of course, you can also create an object directly through the interface, and then implement the default interface methods on it, we show you the code through this way.

public class Main {


  public static void main(String[] args) {

    // TODO 通过匿名内部类方式访问接口

    Formula formula = new Formula() {

        @Override

        public double calculate(int a) {

            return sqrt(a * 100);

        }

    };


    System.out.println(formula.calculate(100));     // 100.0

    System.out.println(formula.sqrt(16));           // 4.0


  }


}

formula is as an anonymous object implements. The code is very easy to understand, the calculation code line 6 sqrt (a * 100). In the next section, we will see there is a more convenient way better in a single method to achieve the object Java 8.

Translator's Note: either abstract classes or interfaces, can be accessed through an anonymous inner class way. Not by abstract classes or interfaces directly create objects. For the above access interface via anonymous inner class way, we can understand: an inner class implements the interface and in the abstract method returns a class object inside, and then we make a reference to the interface point to the object.
Lambda expressions (Lambda expressions)

First, look at the old version of Java is how to arrange the string:

List<String> names = Arrays.asList("peter", "anna", "mike", "xenia");


Collections.sort(names, new Comparator<String>() {

    @Override

    public int compare(String a, String b) {

        return b.compareTo(a);

    }

});

Collections.sort passing just to give a static method and a List object comparators arranged in a specified order. The usual practice is to create a relatively anonymous object and pass it to the sort method.

In Java 8 in this way you will not need to use the traditional object of anonymity, Java 8 provides a more concise syntax, lambda expression:

Collections.sort(names, (String a, String b) -> {

    return b.compareTo(a);

});

As can be seen, the code segment becomes more and more readable, but may in fact be shorter written:

Collections.sort(names, (String a, String b) -> b.compareTo(a));

For the body of the function of only one line of code, you can remove the braces {} and return keyword, but you can also write shorter point:

names.sort((a, b) -> b.compareTo(a));

List class itself is a sort method. And Java compiler can automatically deduce the parameter type, so you can not write once type. Next we look at what other uses lambda expressions.
Functional Interface (Functional Interfaces)

Translator's Note: The original interpretation of this part is not clear, it made changes!

Java language designers have put a lot of effort into thinking about how to make the existing friendly functions support Lambda. The final method is adopted: to increase the concept of functional interface. "Functional Interface" refers only contains only an abstract method, but there may be a plurality of non-abstract methods (i.e. the default method mentioned above) interface. Like interface may be implicitly converted to lambda expressions. java.lang.Runnable with a function interface java.util.concurrent.Callable most typical two examples. Java 8 adds a special notations @FunctionalInterface, but this comment is usually not necessary (in some cases recommended), as long as the interface contains only an abstract method, the virtual interface automatically determine the function interface. General recommended @FunctionalInterface annotations on interface declaration, in this case, the compiler if you find this comment marked interface has more than one abstract method when will complain, as shown below

Example:

@FunctionalInterface

public interface Converter<F, T> {

  T convert(F from);

}

    // TODO 将数字字符串转换为整数类型

    Converter<String, Integer> converter = (from) -> Integer.valueOf(from);

    Integer converted = converter.convert("123");

    System.out.println(converted.getClass()); //class java.lang.Integer

Translator's Note: Most interface function do not write our own, Java8 gave us achieve good, these interfaces are java.util.function bag.
Reference methods and constructors (Method and Constructor References)

Before a code can also be represented by a static method reference:

    Converter<String, Integer> converter = Integer::valueOf;

    Integer converted = converter.convert("123");

    System.out.println(converted.getClass());   //class java.lang.Integer

Java 8 allows you to reference :: by keyword delivery method or constructor. The above example shows how to reference a static method. But we also can refer to object methods:

class Something {

    String startsWith(String s) {

        return String.valueOf(s.charAt(0));

    }

}

Something something = new Something();

Converter<String, String> converter = something::startsWith;

String converted = converter.convert("Java");

System.out.println(converted);    // "J"

Then take a look at how to use the constructor :: keyword to refer, first of all we define a simple class that contains multiple constructors:

class Person {

    String firstName;

    String lastName;


    Person() {}


    Person(String firstName, String lastName) {

        this.firstName = firstName;

        this.lastName = lastName;

    }

}

Next we specify a Person object used to create an object factory interface:

interface PersonFactory<P extends Person> {

    P create(String firstName, String lastName);

}

Here we use a constructor references to associate them together, rather than manually implement a complete factory:

PersonFactory<Person> personFactory = Person::new;

Person person = personFactory.create("Peter", "Parker");

We only need to use Person :: new to get a reference to the Person class constructor, Java compiler will automatically select the appropriate constructor parameters according to the type of PersonFactory.create method.
Lamda expression Scope (Lambda Scopes)
local variables

We can access external local variables directly in the lambda expression:

final int num = 1;

Converter<Integer, String> stringConverter =

        (from) -> String.valueOf(from + num);


stringConverter.convert(2);     // 3

But the anonymity and the object is different, where the num variable can not be declared as final, this code is also true:

int num = 1;

Converter<Integer, String> stringConverter =

        (from) -> String.valueOf(from + num);


stringConverter.convert(2);     // 3

Here num but must not be modified later in the code (i.e., the final having implicit semantics), for example, the following will not compile:

int num = 1;

Converter<Integer, String> stringConverter =

        (from) -> String.valueOf(from + num);

num = 3;//在lambda表达式中试图修改num同样是不允许的。

Access fields and static variables

Compared with local variables, we have read and write access to the lambda expression instance fields and static variables. This behavior is consistent with the object and anonymous.

class Lambda4 {

    static int outerStaticNum;

    int outerNum;


    void testScopes() {

        Converter<Integer, String> stringConverter1 = (from) -> {

            outerNum = 23;

            return String.valueOf(from);

        };


        Converter<Integer, String> stringConverter2 = (from) -> {

            outerStaticNum = 72;

            return String.valueOf(from);

        };

    }

}

Access to the default interface method

Remember the formula in the first example of it? Formula interface defines a default method sqrt, which can be accessed from each of the anonymous formula instance contains object. This does not apply to lambda expressions.

The default method can not be accessed from the lambda expression, so the following code will not compile:

Formula formula = (a) -> sqrt(a * 100);

Interface built-in functions (Built-in Functional Interfaces)

JDK 1.8 API interface contains a number of built-in functions. Some excuse is more common in older versions of Java, such as in: Comparator or Runnable, these interfaces can be used to increase the @FunctionalInterface comment on the lambda expression.

But the same Java 8 API also provides a number of new functional interfaces to make your programming job easier, there are a number of interfaces from Google Guava library, even if you are familiar with these, or it is necessary to look at how these extended to the lambda used.
Predicates

Predicate interface is a Boolean return value of only one parameter assertion type interface. The default method comprises a plurality of interfaces to other complex into the compositions Predicate logic (such as: AND, OR, NOT):

Translator's Note: Predicate Interface Source follows

package java.util.function;

import java.util.Objects;


@FunctionalInterface

public interface Predicate<T> {


    // 该方法是接受一个传入类型,返回一个布尔值.此方法应用于判断.

    boolean test(T t);


    //and方法与关系型运算符"&&"相似,两边都成立才返回true

    default Predicate<T> and(Predicate<? super T> other) {

        Objects.requireNonNull(other);

        return (t) -> test(t) && other.test(t);

    }

    // 与关系运算符"!"相似,对判断进行取反

    default Predicate<T> negate() {

        return (t) -> !test(t);

    }

    //or方法与关系型运算符"||"相似,两边只要有一个成立就返回true

    default Predicate<T> or(Predicate<? super T> other) {

        Objects.requireNonNull(other);

        return (t) -> test(t) || other.test(t);

    }

   // 该方法接收一个Object对象,返回一个Predicate类型.此方法用于判断第一个test的方法与第二个test方法相同(equal).

    static <T> Predicate<T> isEqual(Object targetRef) {

        return (null == targetRef)

                ? Objects::isNull

                : object -> targetRef.equals(object);

    }

Example:

Predicate<String> predicate = (s) -> s.length() > 0;


predicate.test("foo");              // true

predicate.negate().test("foo");     // false


Predicate<Boolean> nonNull = Objects::nonNull;

Predicate<Boolean> isNull = Objects::isNull;


Predicate<String> isEmpty = String::isEmpty;

Predicate<String> isNotEmpty = isEmpty.negate();

Functions

Function interface accepts a parameter and generates the results. The default method may be used to link together a plurality of functions (compose, andThen):

Translator's Note: Function Code Interface follows

package java.util.function;


import java.util.Objects;


@FunctionalInterface

public interface Function<T, R> {


    //将Function对象应用到输入的参数上,然后返回计算结果。

    R apply(T t);

    //将两个Function整合,并返回一个能够执行两个Function对象功能的Function对象。

    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {

        Objects.requireNonNull(before);

        return (V v) -> apply(before.apply(v));

    }

    // 

    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {

        Objects.requireNonNull(after);

        return (T t) -> after.apply(apply(t));

    }


    static <T> Function<T, T> identity() {

        return t -> t;

    }

}

Function<String, Integer> toInteger = Integer::valueOf;

Function<String, String> backToString = toInteger.andThen(String::valueOf);

backToString.apply("123");     // "123"

Suppliers

Supplier interface generates a generic type for a given result. Function interfaces with different, Supplier interface does not accept parameters.

Supplier<Person> personSupplier = Person::new;

personSupplier.get();   // new Person

Consumers

Consumer Interface represents operating parameters to be performed on a single input.

Consumer<Person> greeter = (p) -> System.out.println("Hello, " + p.firstName);

greeter.accept(new Person("Luke", "Skywalker"));

Comparators

Comparator is an old classic interfaces in Java, Java 8 is added on top of this a number of default method:

Comparator<Person> comparator = (p1, p2) -> p1.firstName.compareTo(p2.firstName);


Person p1 = new Person("John", "Doe");

Person p2 = new Person("Alice", "Wonderland");


comparator.compare(p1, p2);             // > 0

comparator.reversed().compare(p1, p2);  // < 0

Optionals

Optionals is not a function interface, but nice tool for preventing NullPointerException. This is an important concept in the next section, let's take a quick look at the works Optionals.

Optional is a simple container, whose value may be null or not null. Before Java 8 is generally a function should return a non-null object but sometimes nothing is returned, while in Java 8, you should return Optional instead of null.

Translator's Note: the role of each exemplary method has been added.

//of():为非null的值创建一个Optional

Optional<String> optional = Optional.of("bam");

// isPresent(): 如果值存在返回true,否则返回false

optional.isPresent();           // true

//get():如果Optional有值则将其返回,否则抛出NoSuchElementException

optional.get();                 // "bam"

//orElse():如果有值则将其返回,否则返回指定的其它值

optional.orElse("fallback");    // "bam"

//ifPresent():如果Optional实例有值则为其调用consumer,否则不做处理

optional.ifPresent((s) -> System.out.println(s.charAt(0)));     // "b"

Recommended reading: [Java8] how to correctly use Optional
Streams (stream)

java.util.Stream showing the sequence of operations can be applied in the first performance of a group of elements. Stream operation into intermediate or final operation of two kinds of operation, operation returns the final result of a particular type of calculation, the operation returns to the intermediate Stream itself, so you can operate sequentially a plurality of strings together. Stream of creation need to specify a data source, such as java.util.Collection subclass, List or Set, Map is not supported. Stream operations can be performed serially or in parallel.

Stream is the first look at how to use the first instance of the data used to create the code of List:

List<String> stringCollection = new ArrayList<>();

stringCollection.add("ddd2");

stringCollection.add("aaa2");

stringCollection.add("bbb1");

stringCollection.add("aaa1");

stringCollection.add("bbb3");

stringCollection.add("ccc");

stringCollection.add("bbb2");

stringCollection.add("ddd1");

Java 8 extends the collection class, you can create a Stream by Collection.stream () or Collection.parallelStream (). The following sections explain in detail the operation Stream common:
the Filter (Filter)

Filtered through a filter predicate an interface and retain only qualified elements, which belong to the middle operation operation, so we can result in the application of other filtration Stream operations (such as forEach). forEach requires a function to sequentially perform the filtering element. forEach is a final operation, so we can not then perform other operations in forEach the Stream.

        // 测试 Filter(过滤)

        stringList

                .stream()

                .filter((s) -> s.startsWith("a"))

                .forEach(System.out::println);//aaa2 aaa1

forEach Lambda is designed to keep the most compact style. And Lambda expression itself is reusable, very convenient.
Sorted (sorting)

Intermediate is a sort operation, returns after a good Stream sorted. If you do not specify a custom Comparator will use the default sort.

        // 测试 Sort (排序)

        stringList

                .stream()

                .sorted()

                .filter((s) -> s.startsWith("a"))

                .forEach(System.out::println);// aaa1 aaa2

It should be noted that only creates the sort Stream after a good arrangement, and will not affect the original data source, the original data is not modified after stringCollection sorted:

    System.out.println(stringList);// ddd2, aaa2, bbb1, aaa1, bbb3, ccc, bbb2, ddd1

Map (map)

Intermediate operation will map elements sequentially turn into another element of the object based on the specified interface Function.

The following example shows Converts a string to upper case string. You can also be converted into other types of objects concerned by a map, Stream type map is returned according to the function return value passed in your map determined.

        // 测试 Map 操作

        stringList

                .stream()

                .map(String::toUpperCase)

                .sorted((a, b) -> b.compareTo(a))

                .forEach(System.out::println);// "DDD2", "DDD1", "CCC", "BBB3", "BBB2", "AAA2", "AAA1"

Match (match)

Stream Providing multiple matching operation, allows detection of the entire match the specified Predicate Stream. All matching operation is the final operation, and returns a boolean value.

        // 测试 Match (匹配)操作

        boolean anyStartsWithA =

                stringList

                        .stream()

                        .anyMatch((s) -> s.startsWith("a"));

        System.out.println(anyStartsWithA);      // true


        boolean allStartsWithA =

                stringList

                        .stream()

                        .allMatch((s) -> s.startsWith("a"));


        System.out.println(allStartsWithA);      // false


        boolean noneStartsWithZ =

                stringList

                        .stream()

                        .noneMatch((s) -> s.startsWith("z"));


        System.out.println(noneStartsWithZ);      // true

Count (Count)

Count is a final operation, returns the number of elements in the Stream, the return type is long.

      //测试 Count (计数)操作

        long startsWithB =

                stringList

                        .stream()

                        .filter((s) -> s.startsWith("b"))

                        .count();

        System.out.println(startsWithB);    // 3

Reduce (statute)

This is a final operation, by specifying the function in terms of allowing a plurality of elements in a stream statute element, the result is indicated by the statute Optional interfaces:

        //测试 Reduce (规约)操作

        Optional<String> reduced =

                stringList

                        .stream()

                        .sorted()

                        .reduce((s1, s2) -> s1 + "#" + s2);


        reduced.ifPresent(System.out::println);//aaa1#aaa2#bbb1#bbb2#bbb3#ccc#ddd1#ddd2

Translator's Note: The main role of this method is to combine elements of Stream. It provides a start value (seed), then in accordance with the calculation rule (BinaryOperator), and a front of the Stream, the second, the n-th element combination. In this sense, string concatenation, sum value, min, max, average are special reduce. For example, the sum is equivalent Stream Integersum = integers.reduce (0, (a, b) -> a + b); there is no case where the starting value, then the first two elements will combine Stream returned It is Optional.

// 字符串连接,concat = "ABCD"

String concat = Stream.of("A", "B", "C", "D").reduce("", String::concat); 

// 求最小值,minValue = -3.0

double minValue = Stream.of(-1.5, 1.0, -3.0, -2.0).reduce(Double.MAX_VALUE, Double::min); 

// 求和,sumValue = 10, 有起始值

int sumValue = Stream.of(1, 2, 3, 4).reduce(0, Integer::sum);

// 求和,sumValue = 10, 无起始值

sumValue = Stream.of(1, 2, 3, 4).reduce(Integer::sum).get();

// 过滤,字符串连接,concat = "ace"

concat = Stream.of("a", "B", "c", "D", "e", "F").

 filter(x -> x.compareTo("Z") > 0).

 reduce("", String::concat);

Reduce the above code example, the first example (), the first parameter (blank character) is the start value, the second parameter (String :: concat) is BinaryOperator. Such has reduce the starting value () returns a specific object. For example there is no fourth start value of reduce (), may not be enough because the elements, returns Optional, please pay attention to this distinction. View more content: IBM: Java Streams API 8 Detailed
Parallel Streams (parallel flow)

Stream previously mentioned have both serial and parallel, serial Stream operations on sequentially done in a thread, in parallel Stream is performed simultaneously on multiple threads.

The following example shows how to improve performance through parallel Stream:

First, we create a large table no duplicate elements:

int max = 1000000;

List<String> values = new ArrayList<>(max);

for (int i = 0; i < max; i++) {

    UUID uuid = UUID.randomUUID();

    values.add(uuid.toString());

}

We were with both serial and parallel ways to sort them, and finally look at the comparison of time spent.
Sequential Sort (serial ordering)

//串行排序

long t0 = System.nanoTime();

long count = values.stream().sorted().count();

System.out.println(count);


long t1 = System.nanoTime();


long millis = TimeUnit.NANOSECONDS.toMillis(t1 - t0);

System.out.println(String.format("sequential sort took: %d ms", millis));

1000000

sequential sort took: 709 ms//串行排序所用的时间

Parallel Sort (parallel sort)

//并行排序

long t0 = System.nanoTime();


long count = values.parallelStream().sorted().count();

System.out.println(count);


long t1 = System.nanoTime();


long millis = TimeUnit.NANOSECONDS.toMillis(t1 - t0);

System.out.println(String.format("parallel sort took: %d ms", millis));

1000000

parallel sort took: 475 ms//串行排序所用的时间

The above two codes is almost the same, but the parallel version of the faster 50%, the only need to do is change the stream () instead parallelStream ().
Maps

As mentioned earlier, Map type does not support streams, but Map provides some new and useful ways to deal with some everyday tasks. Map interface itself is not available stream () method, but you can create a dedicated stream on the key, value, or by map.keySet (). Stream (), map.values ​​(). Stream () and map.entrySet () .stream ().

Additionally, Maps support a variety of new and useful ways to perform common tasks.

Map<Integer, String> map = new HashMap<>();


for (int i = 0; i < 10; i++) {

    map.putIfAbsent(i, "val" + i);

}


map.forEach((id, val) -> System.out.println(val));//val0 val1 val2 val3 val4 val5 val6 val7 val8 val9

putIfAbsent stop us write extra code in the null checks; forEach to accept a consumer to map each element in the operation.

This example shows how to use the function on the map calculated in the code:

map.computeIfPresent(3, (num, val) -> val + num);

map.get(3);             // val33


map.computeIfPresent(9, (num, val) -> null);

map.containsKey(9);     // false


map.computeIfAbsent(23, num -> "val" + num);

map.containsKey(23);    // true


map.computeIfAbsent(3, num -> "bam");

map.get(3);             // val33

Next we show how to remove all items matching a key in the Map:

map.remove(3, "val3");

map.get(3);             // val33

map.remove(3, "val33");

map.get(3);             // null

Another useful method:

map.getOrDefault(42, "not found");  // not found

Map of the elements to make the merger has become very easy:

map.merge(9, "val9", (value, newValue) -> value.concat(newValue));

map.get(9);             // val9

map.merge(9, "concat", (value, newValue) -> value.concat(newValue));

map.get(9);             // val9concat

Merge do is if the key is inserted into the name does not exist, or the corresponding key on the original value do merge operations and re-inserted into the map.
Data API (the date of the relevant API)

Java 8 contains a new date and time API in java.time package. New Date API and Joda-Time library similar, but they are not the same. The following examples cover the most important part of this new API. Translator reference to this part of the contents of books made most of the changes.

Translator's Note (summary):

Clock 类提供了访问当前日期和时间的方法,Clock 是时区敏感的,可以用来取代 System.currentTimeMillis() 来获取当前的微秒数。某一个特定的时间点也可以使用 Instant 类来表示, Instant 类也可以用来创建旧版本的 java.util.Date 对象。



在新API中时区使用 ZoneId 来表示。时区可以很方便的使用静态方法of来获取到。 抽象类 ZoneId(在 java.time包中)表示一个区域标识符。 它有一个名为 getAvailableZoneIds的静态方法,它返回所有区域标识符。



jdk1.8中新增了 LocalDate 与 LocalDateTime等类来解决日期处理方法,同时引入了一个新的类DateTimeFormatter 来解决日期格式化问题。可以使用Instant代替 Date,LocalDateTime代替 Calendar,DateTimeFormatter 代替 SimpleDateFormat。

Clock

Clock class provides access to the current date and time, the time zone is sensitive Clock, it may be used instead System.currentTimeMillis () to get the current of a few microseconds. A particular point in time can also be used to represent the class Instant, Instant classes can also be used to create the old version of java.util.Date object.

Clock clock = Clock.systemDefaultZone();

long millis = clock.millis();

System.out.println(millis);//1552379579043

Instant instant = clock.instant();

System.out.println(instant);

Date legacyDate = Date.from(instant); //2019-03-12T08:46:42.588Z

System.out.println(legacyDate);//Tue Mar 12 16:32:59 CST 2019

Timezones (time zone)

Time zone using the new API in ZoneId to represent. Time zone can easily use the static method of to get to. ZoneID ID of the abstract class (in java.time package) represents a region identifier. It has a static method called getAvailableZoneIds, which returns all area identifier.

//输出所有区域标识符

System.out.println(ZoneId.getAvailableZoneIds());


ZoneId zone1 = ZoneId.of("Europe/Berlin");

ZoneId zone2 = ZoneId.of("Brazil/East");

System.out.println(zone1.getRules());// ZoneRules[currentStandardOffset=+01:00]

System.out.println(zone2.getRules());// ZoneRules[currentStandardOffset=-03:00]

LocalTime (local time)

LocalTime defines the time without a time zone information, for example, 22:00 or 17:30:15. The following example uses the previous code created when creating the two local time zone. After the comparison and the time in hours and minutes the time difference calculating two time:

LocalTime now1 = LocalTime.now(zone1);

LocalTime now2 = LocalTime.now(zone2);

System.out.println(now1.isBefore(now2));  // false


long hoursBetween = ChronoUnit.HOURS.between(now1, now2);

long minutesBetween = ChronoUnit.MINUTES.between(now1, now2);


System.out.println(hoursBetween);       // -3

System.out.println(minutesBetween);     // -239

LocalTime provides several methods to simplify the creation of factory object includes parsing a string time.

LocalTime late = LocalTime.of(23, 59, 59);

System.out.println(late);       // 23:59:59

DateTimeFormatter germanFormatter =

    DateTimeFormatter

        .ofLocalizedTime(FormatStyle.SHORT)

        .withLocale(Locale.GERMAN);


LocalTime leetTime = LocalTime.parse("13:37", germanFormatter);

System.out.println(leetTime);   // 13:37

LocalDate (local date)

LocalDate represents an exact date, such as 2014-03-11. This object is immutable value, together with the consistent and LocalTime. The following example shows how to add and subtract objects Date day / month / year. Also note that these objects are immutable, a new instance of the operation is always returned.

LocalDate today = LocalDate.now();//获取现在的日期

System.out.println("今天的日期: "+today);//2019-03-12

LocalDate tomorrow = today.plus(1, ChronoUnit.DAYS);

System.out.println("明天的日期: "+tomorrow);//2019-03-13

LocalDate yesterday = tomorrow.minusDays(2);

System.out.println("昨天的日期: "+yesterday);//2019-03-11

LocalDate independenceDay = LocalDate.of(2019, Month.MARCH, 12);

DayOfWeek dayOfWeek = independenceDay.getDayOfWeek();

System.out.println("今天是周几:"+dayOfWeek);//TUESDAY

From as simple a LocalDate type string parsing and parsing LocalTime, following is an example of using DateTimeFormatter parse the string:

    String str1 = "2014==04==12 01时06分09秒";

        // 根据需要解析的日期、时间字符串定义解析所用的格式器

        DateTimeFormatter fomatter1 = DateTimeFormatter

                .ofPattern("yyyy==MM==dd HH时mm分ss秒");


        LocalDateTime dt1 = LocalDateTime.parse(str1, fomatter1);

        System.out.println(dt1); // 输出 2014-04-12T01:06:09


        String str2 = "2014$$$四月$$$13 20小时";

        DateTimeFormatter fomatter2 = DateTimeFormatter

                .ofPattern("yyy$$$MMM$$$dd HH小时");

        LocalDateTime dt2 = LocalDateTime.parse(str2, fomatter2);

        System.out.println(dt2); // 输出 2014-04-13T20:00

Let's look at a formatted date using exemplary DateTimeFormatter

LocalDateTime rightNow=LocalDateTime.now();

String date=DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(rightNow);

System.out.println(date);//2019-03-12T16:26:48.29

DateTimeFormatter formatter=DateTimeFormatter.ofPattern("YYYY-MM-dd HH:mm:ss");

System.out.println(formatter.format(rightNow));//2019-03-12 16:26:48

LocalDateTime (local date and time)

LocalDateTime also said the time and date corresponding to the first two is incorporated into the object. LocalDateTime and LocalTime there LocalDate, are immutable. LocalDateTime provides methods to access specific fields.

LocalDateTime sylvester = LocalDateTime.of(2014, Month.DECEMBER, 31, 23, 59, 59);


DayOfWeek dayOfWeek = sylvester.getDayOfWeek();

System.out.println(dayOfWeek);      // WEDNESDAY


Month month = sylvester.getMonth();

System.out.println(month);          // DECEMBER


long minuteOfDay = sylvester.getLong(ChronoField.MINUTE_OF_DAY);

System.out.println(minuteOfDay);    // 1439

As long as additional information on the time zone, you can convert it to a target point in time Instant, Instant time objects can easily be converted into old-fashioned java.util.Date.

Instant instant = sylvester

        .atZone(ZoneId.systemDefault())

        .toInstant();


Date legacyDate = Date.from(instant);

System.out.println(legacyDate);     // Wed Dec 31 23:59:59 CET 2014

LocalDateTime formatting and formatting time and date of the same, in addition to using pre-defined format, we can define your own format:

DateTimeFormatter formatter =

    DateTimeFormatter

        .ofPattern("MMM dd, yyyy - HH:mm");

LocalDateTime parsed = LocalDateTime.parse("Nov 03, 2014 - 07:13", formatter);

String string = formatter.format(parsed);

System.out.println(string);     // Nov 03, 2014 - 07:13

And java.text.NumberFormat not the same as a new version of DateTimeFormatter are immutable, so it is thread-safe.
For more information about the date and time format here.
Annotations (notes)

Support multiple annotations in the Java 8, look at an example to understand what is meant.
First define a wrapper class annotation Hints for placing a specific set of annotations Hint:

@interface Hints {

    Hint[] value();

}

@Repeatable(Hints.class)

@interface Hint {

    String value();

}

Java 8 allows us to use the same type of comment many times, just give the notes to label what @Repeatable.

Example 1: When using the packaging container for a plurality of stored annotations (old method)

@Hints({@Hint("hint1"), @Hint("hint2")})

class Person {}

Example 2: Use of multiple annotations (new method)

@Hint("hint1")

@Hint("hint2")

class Person {}

The second example in java compiler will help you define the implicit good @Hints notes, it helps you understand the use reflection to get this information:

Hint hint = Person.class.getAnnotation(Hint.class);

System.out.println(hint);                   // null

Hints hints1 = Person.class.getAnnotation(Hints.class);

System.out.println(hints1.value().length);  // 2


Hint[] hints2 = Person.class.getAnnotationsByType(Hint.class);

System.out.println(hints2.length);          // 2

Even if we do not define @Hints annotation on the Person class, we can getAnnotation (Hints.class) to get @Hints notes, more convenient way is to use getAnnotationsByType can get directly to all of @Hint comment.
In addition Java annotations 8 also increased on the two new target:

@Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})

@interface MyAnnotation {}

Guess you like

Origin blog.csdn.net/qq_40775293/article/details/94741354