"Java는 여전히 죽지 않았으며 사람들은 그것을 알아 내기 시작했습니다."
이 튜토리얼은 간단한 주석이 달린 코드를 사용하여 새로운 기능을 설명하며 블록버스터 텍스트가 표시되지 않습니다.
1. 인터페이스의 기본 메소드
Java 8을 사용하면 비 임금 메소드 구현을 인터페이스에 추가 할 수 있습니다. 기본 키워드는 다음과 같습니다.
코드 사본은 다음과 같습니다.
인터페이스 공식 {
이중 계산 (int a);
기본 이중 SQRT (int A) {
반환 수학 .sqrt (a);
}
}
계산 된 방법을 갖는 것 외에도 공식 인터페이스는 공식 인터페이스를 구현하는 SQRT 메소드를 정의하면 계산 된 메소드 만 구현하면 기본 메소드 SQRT가 서브 클래스에서 직접 사용됩니다.
코드 사본은 다음과 같습니다.
공식 공식 = 새로운 공식 () {
@보수
공개 이중 계산 (int a) {
반환 sqrt (a * 100);
}
};
공식화 (100);
포뮬러 .sqrt (16);
이 기사의 공식은 익명 클래스의 인스턴스로 구현됩니다. 다음 섹션에서는 단일 방법 인터페이스를 구현하는 데 더 간단한 접근 방식이 표시됩니다.
번역가 주 : Java에는 단일 상속이 있으며, 새로운 기능을 클래스에 할당하려면 보통 C ++에서 여러 상속이 지원됩니다. 다른 언어에서는 클래스를 갖는 방법을 동시에 다른 재사용 가능한 코드를 갖는 방법을 Mixin이라고합니다. 이 새로운 Java 8 스페셜은 컴파일러 구현의 관점에서 Scala의 특성에 더 가깝습니다. C#에는 확장 메소드라는 개념이 있으며, 이는 기존 유형을 확장 할 수 있으며, 이는 Java 8에서 의미 적으로 다릅니다.
2. 람다 표현
먼저, 구형 버전의 Java에서 문자열이 어떻게 배열되는지 살펴 보겠습니다.
코드 사본은 다음과 같습니다.
list <string> names = arrays.aslist ( "Peter", "Anna", "Mike", "Xenia");
collections.sort (이름, 새 비교기 <문자열> () {
@보수
public int 비교 (문자열 a, 문자열 b) {
반품 b.compareto (a);
}
});
목록 객체와 비교기를 정적 메서드 컬렉션에 전달하십시오. 일반적으로 익명 비교기 객체를 만들어 정렬 방법으로 전달하는 것이 수행됩니다.
Java 8에서는이 전통적인 익명의 객체를 사용할 필요가 없습니다.
코드 사본은 다음과 같습니다.
collections.sort (이름, (문자열 a, 문자열 b) -> {
반품 b.compareto (a);
});
코드가 더 분할되고 읽을 수있게되지만 실제로는 더 짧게 쓸 수 있습니다.
코드 사본은 다음과 같습니다.
collections.sort (이름, (문자열 a, 문자열 b) -> b.compareto (a));
코드 한 줄만있는 기능 본문의 경우 브레이스 {}를 제거하고 키워드를 반환 할 수 있지만 더 짧게 쓸 수 있습니다.
코드 사본은 다음과 같습니다.
collections.sort (이름, (a, b) -> b.compareto (a));
Java 컴파일러는 매개 변수 유형을 자동으로 추론 할 수 있으므로 유형을 다시 작성할 필요가 없습니다. 다음으로, 더 편리한 람다 표현이 무엇을 할 수 있는지 보자.
3. 기능 인터페이스
Java의 유형 시스템에서 Lambda 표현은 어떻게 표현됩니까? 각 람다 표현식은 유형, 일반적으로 인터페이스 유형에 해당합니다. "기능 인터페이스"는 추상 방법 만 포함하는 인터페이스를 나타냅니다.이 유형의 각 람다 표현식은이 추상 방법과 일치합니다. 기본 메소드는 추상 메소드가 아니기 때문에 기능 인터페이스에 기본 메소드를 추가 할 수도 있습니다.
Lambda 표현식은 인터페이스 가이 요구 사항을 충족 해야하는 하나의 추상 방법 만 포함하는 인터페이스 유형으로 처리 할 수 있습니다. 주석, 컴파일러는 당신이 표시 한 인터페이스 가이 주석에 의해 주석이 붙어 있음을 발견합니다.
예는 다음과 같습니다.
코드 사본은 다음과 같습니다.
@functionalinterface
인터페이스 변환기 <f, t> {
t 변환 (f에서);
}
변환기 <문자열, 정수> 변환기 = (From) -> integer.valueof (from);
정수 변환 = converter.convert ( "123");
System.out.println (변환);
@functionalInterface가 지정되지 않은 경우 위의 코드도 정확합니다.
번역가는 람다 표현식이 단일 메드 인터페이스에 대한 다른 언어로 구현되었습니다. Rhino 통역사는 자동으로 기능 어댑터에 대한 인스턴스를 만듭니다.
4. 방법 및 생성자 참조
이전 섹션의 코드는 정적 메소드 참조로 표시 될 수도 있습니다.
코드 사본은 다음과 같습니다.
변환기 <문자열, 정수> 변환기 = 정수 :: valueof;
정수 변환 = converter.convert ( "123");
System.out.println (변환);
Java 8을 사용하면 :: 키워드를 사용하여 메소드 또는 생성자 참조를 전달할 수 있습니다.
코드 사본은 다음과 같습니다.
converter = something :: startswith;
문자열 converted = conver.convert ( "java");
System.out.println (변환); // "J"
:: 키워드를 사용하여 생성자를 참조하는 방법을 살펴 보겠습니다.
코드 사본은 다음과 같습니다.
클래스 사람 {
문자열 firstName;
문자열 마지막 이름;
사람() {}
Person (String FirstName, String lastName) {
this.firstName = FirstName;
this.lastname = lastName;
}
}
다음으로 개인 객체를 만들기 위해 객체 팩토리 인터페이스를 지정합니다.
코드 사본은 다음과 같습니다.
인터페이스 personfactory <p는 사람> {
p create (string firstName, String lastName);
}
여기서 우리는 전체 공장을 구현하는 대신 생성자 참조를 사용합니다.
코드 사본은 다음과 같습니다.
PersonFactory <person> personfactory = person :: new;
Person Person = personfactory.create ( "Peter", "Parker");
Person Class 생성자에 대한 참조를 얻으려면 사람 :: 새로운 사람 만 사용하면 PersonFactory.Create 메소드의 서명에 따라 적절한 생성자를 자동으로 선택합니다.
5. 람다 범위
Lambda 표현식에서 외부 스코프에 액세스하는 방법은 기존 버전의 익명 객체와 유사합니다. 최종적으로 표시된 외부 로컬 변수 또는 인스턴스의 필드 및 정적 변수에 직접 액세스 할 수 있습니다.
6. 로컬 변수에 액세스하십시오
Lambda 표현식으로 외부 로컬 변수에 직접 액세스 할 수 있습니다.
코드 사본은 다음과 같습니다.
최종 int num = 1;
변환기 <정수, String> StringConverter =
(From) -> String.Valueof (From + Num);
StringConverter.convert (2);
그러나 익명 객체와 달리 여기서 변수 NUM은 최종으로 선언하지 않고 최종적으로 선언 할 수 있으며 코드도 정확합니다.
코드 사본은 다음과 같습니다.
int num = 1;
변환기 <정수, String> StringConverter =
(From) -> String.Valueof (From + Num);
StringConverter.convert (2);
그러나 여기에서 NUM은 후속 코드에 의해 수정되어서는 안됩니다 (즉, 암시 적으로 최종 의미가 있음). 예를 들어 다음은 편집 할 수 없습니다.
코드 사본은 다음과 같습니다.
int num = 1;
변환기 <정수, String> StringConverter =
(From) -> String.Valueof (From + Num);
num = 3;
Lambda 표현식에서 NUM을 수정하려고 시도하는 것도 허용되지 않습니다.
7. 객체 필드 및 정적 변수에 액세스하십시오
로컬 변수와 달리 Lambda 내의 필드 및 정적 변수를 읽고 쓸 수 있습니다. 이 동작은 익명 대상과 일치합니다.
다음과 같이 코드를 복사하십시오 : 클래스 lambda4 {
정적 int 외피;
int outernum;
void testscopes () {
변환기 <정수, String> StringConverter1 = (from) -> {
outernum = 23;
return string.valueof (from);
};
변환기 <정수, String> StringConverter2 = (from) -> {
auterstaticnum = 72;
return string.valueof (from);
};
}
}
8. 인터페이스에 액세스하는 기본 메소드
첫 번째 섹션에서 공식 예제를 기억하십시오. 인터페이스 공식은 익명 객체를 포함한 공식 인스턴스에서 직접 액세스 할 수있는 기본 메소드 SQRT를 정의하지만 Lambda 표현식에서는 작동하지 않습니다.
Lambda 표현식에서는 기본 메소드에 액세스 할 수 없으며 다음 코드는 컴파일되지 않습니다.
코드 사본은 다음과 같습니다.
공식 공식 = (a) -> sqrt (a * 100);
내장 기능 인터페이스
JDK 1.8 API에는 오래된 Java에서 일반적으로 사용되는 비교기 또는 런닝 가능한 인터페이스와 같은 많은 내장 기능 인터페이스가 포함되어 있으며 이러한 인터페이스에는 Lambdas에서 사용할 @functionalinterface 주석이 추가되었습니다.
Java 8 API는 또한 많은 새로운 기능적 인터페이스를 제공합니다.
술어 인터페이스
술어 인터페이스에는 부울 유형을 반환하는 매개 변수가 하나뿐입니다. 이 인터페이스에는 술어를 다른 복잡한 논리 (예 : : vers, 또는 non)에 결합하는 여러 기본 메소드가 포함되어 있습니다.
코드 사본은 다음과 같습니다.
술어 <문자열> 술어 = (s) -> s.length ()> 0;
predict.test ( "foo");
predict.negate (). test ( "foo");
술어 <boolean> nonnull = Objects :: nonnull;
술어 <boolean> isnull = Objects :: isnull;
술어 <string> isempty = string :: isempty;
술어 <String> ISNOTEMPTY = ISEMPTY.NEGATE ();
기능 인터페이스
함수 인터페이스에는 매개 변수가 있으며 결과를 반환하며 다른 기능과 결합 할 수있는 몇 가지 기본 메소드 (Compose, andthen)가 제공됩니다.
코드 사본은 다음과 같습니다.
함수 <문자열, 정수> tointeger = integer :: valueof;
function <string, String> backtostring = tointeger.andthen (String :: valueOf);
backtostring.apply ( "123");
공급 업체 인터페이스
공급 업체 인터페이스는 모든 유형의 값을 반환합니다. 함수 인터페이스와 달리 인터페이스에는 매개 변수가 없습니다.
코드 사본은 다음과 같습니다.
공급 업체 <personsupplier = person :: new;
personsupplier.get ();
소비자 인터페이스
소비자 인터페이스는 단일 매개 변수에서 수행되는 작업을 나타냅니다.
코드 사본은 다음과 같습니다.
소비자 <perseeter = (p) -> system.out.println ( "hello," + p.firstname);
greeter.ccept (새로운 사람 ( "Luke", "Skywalker"));
비교기 인터페이스
비교기는 오래된 Java의 고전적인 인터페이스이며 Java 8은 다양한 기본 메소드를 추가했습니다.
코드 사본은 다음과 같습니다.
비교기 <person> 비교기 = (p1, p2) -> p1.firstname.compareto (p2.firstname);
Person P1 = 새로운 사람 ( "John", "Doe");
Person P2 = 새로운 사람 ( "Alice", "Wonderland");
비교 전파 (p1, p2);
비교. reversed (). 비교 (p1, p2);
선택적 인터페이스
옵션은 기능이 아니라 NullPointerException을 방지하는 데 사용되는 보조 유형입니다.
선택 사항은 값이 무효인지 아닌 간단한 컨테이너로 정의됩니다. Java 8 이전에 함수는 일반적으로 비어 있지 않은 물체를 반환해야하지만 때로는 Java 8에서 NULL을 반환 할 수 있습니다.
코드 사본은 다음과 같습니다.
옵션 <string> 옵션 = 선택 사항 ( "bam");
옵션 .icpresent ();
옵션 (); // "bam"
옵션 orelse ( "폴백");
옵션 .ifpresent ((s) -> system.out.println (s.charat (0));
스트림 인터페이스
java.util.stream은 일련의 요소에 한 번에 적용 할 수있는 일련의 연산을 나타냅니다. 스트림 작업은 중간 작업 또는 최종 작업의 두 가지 유형으로 나뉩니다. 최종 작업은 특정 유형의 계산 결과를 반환하고 중간 작업은 스트림 자체를 반환하여 여러 작업을 순서대로 함께 연결할 수 있습니다. 스트림 생성은 java.util.collection, list 또는 set의 서브 클래스와 같은 데이터 소스를 지정해야하며, 이는 MAP에서 지원하지 않습니다. 스트림 작업은 연속적 또는 병렬로 실행할 수 있습니다.
먼저 스트림 사용 방법을 살펴 보겠습니다. 인스턴스 코드를 작성하는 데 사용되는 데이터 목록을 작성하십시오.
코드 사본은 다음과 같습니다.
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은 컬렉션 클래스를 확장하고 collection.stream () 또는 collection.parallelstream ()을 통해 스트림을 만들 수 있습니다. 다음 섹션에서는 일반적으로 사용되는 스트림 작업을 자세히 설명합니다.
필터 필터
필터링은 술어 인터페이스를 통해 필터링되며 기준을 충족하는 요소만이 작업이 중간 작업이므로 필터링 된 결과에 다른 스트림 작업 (예 : Foreach)을 적용 할 수 있습니다. Foreach는 필터링 된 요소를 순서대로 실행하려면 함수가 필요합니다. Foreach는 최종 작업이므로 Foreach 후에 다른 스트림 작업을 수행 할 수 없습니다.
코드 사본은 다음과 같습니다.
StringCollection
.개울()
.filter ((S) -> S.startSwith ( "A"))
.foreach (system.out :: println);
// "aaa2", "aaa1"
정렬 정렬
정렬은 중간 작업이며 정렬 후 리턴 스트림이 반환됩니다. 사용자 정의 비교기를 지정하지 않으면 기본 정렬이 사용됩니다.
코드 사본은 다음과 같습니다.
StringCollection
.개울()
.sorted ()
.filter ((S) -> S.startSwith ( "A"))
.foreach (system.out :: println);
// "aaa1", "aaa2"
정렬은 정렬 된 스트림 만 생성하며 원래 데이터 소스에 영향을 미치지 않으면 원래 데이터 문자열을 수정하지 않습니다.
코드 사본은 다음과 같습니다.
System.out.println (StringCollection);
// DDD2, AAA2, BBB1, AAA1, BBB3, CCC, BBB2, DDD1
지도 매핑
중간 작동 맵은 지정된 함수 인터페이스에 따라 요소를 순서대로 변환합니다. 맵을 사용하여 객체를 다른 유형으로 변환 할 수 있습니다. 맵에 의해 리턴 된 스트림 유형은 맵에 의해 전달 된 함수의 반환 값에 따라 결정됩니다.
코드 사본은 다음과 같습니다.
StringCollection
.개울()
.map (String :: ToupperCase)
.SORTED ((A, B) -> B.comPareto (A))
.foreach (system.out :: println);
// "ddd2", "ddd1", "ccc", "bbb3", "bbb2", "aaa2", "aaa1"
성냥
Stream은 다양한 일치하는 작업을 제공하여 지정된 술어가 전체 스트림과 일치하는지 여부를 감지 할 수 있습니다. 모든 일치하는 작업은 최종 작업이며 부울 유형의 값을 반환합니다.
코드 사본은 다음과 같습니다.
부울 anystartswitha =
StringCollection
.개울()
.anymatch ((s) -> s.startswith ( "a"));
System.out.println (anystartswitha);
부울 allstartswitha =
StringCollection
.개울()
.allMatch ((s) -> s.startSwith ( "a"));
System.out.println (allstartswitha);
부울 nonstartswithz =
StringCollection
.개울()
.Nonematch ((s) -> s.startswith ( "z"));
System.out.println (nonestartswithz);
세다
카운팅은 최종 작업으로 스트림의 요소 수를 반환하고 반환 값 유형이 길다.
코드 사본은 다음과 같습니다.
Long Startswithb =
StringCollection
.개울()
.filter ((S) -> S.startSwith ( "B"))
.세다();
System.out.println (startswithb);
규정을 줄입니다
이것은 최종 작업으로, 스트림의 여러 요소가 지정된 함수를 통해 하나의 요소로 정의 될 수 있으며, 자격의 결과는 선택적 인터페이스로 표시됩니다.
코드 사본은 다음과 같습니다.
옵션 <문자열> 축소 =
StringCollection
.개울()
.sorted ()
.reduce ((S1, S2) -> S1 + "#" + S2);
삭제. ifpresent (System.out :: println);
// "aaa1#aaa2#bb1#bb2#bb3#ccc#ddd1#ddd2"
평행 스트림
앞에서 언급 한 바와 같이, 스트림에는 일련의 연산이 하나의 스레드에서 순서대로 완료되며 평행 스트림은 여러 스레드에서 동시에 실행됩니다.
다음 예는 병렬 스트림을 통해 성능을 향상시키는 방법을 보여줍니다.
먼저 중복 요소가없는 큰 테이블을 만듭니다.
코드 사본은 다음과 같습니다.
int max = 10000000;
List <string> value = new ArrayList <> (max);
for (int i = 0; i <max; i ++) {
uuid uuid = uuid.randomuuid ();
values.add (uuid.tostring ());
}
그런 다음이 스트림을 정렬하는 데 걸리는 시간을 계산합니다.
일련의 정렬 :
코드 사본은 다음과 같습니다.
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 ( "순차 정렬 : %d ms", millis);
// 일련 시간 : 899ms
병렬 분류 :
코드 사본은 다음과 같습니다.
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 ( "병렬 정렬 : %d ms", millis);
// 병렬 분류는 시간이 걸립니다 : 472ms
위의 두 코드는 거의 동일하지만 병렬 버전은 50%정도입니다.
지도
앞에서 언급했듯이 맵 유형은 스트림을 지원하지 않지만 MAP는 일상적인 작업을 처리하는 새롭고 유용한 방법을 제공합니다.
코드 사본은 다음과 같습니다.
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));
위의 코드는 이해하기 쉽습니다. Putifabsent는 추가 존재 점검을 수행 할 필요가 없으며 Foreach는 맵의 각 키 값 쌍에서 작동하기 위해 소비자 인터페이스를 수신합니다.
다음 예제는지도에서 다른 유용한 기능을 보여줍니다.
코드 사본은 다음과 같습니다.
map.computeifpresent (3, (num, val) -> val + num);
map.get (3);
map.comPuteIfPresent (9, (Num, Val) -> NULL);
Map.Containskey (9);
map.computeifabsent (23, num-> "val" + num);
Map.Containskey (23);
map.computeifabsent (3, num-> "bam");
map.get (3);
다음으로 모든 키와 일치하는 맵에서 항목을 삭제하는 방법을 보여줍니다.
코드 사본은 다음과 같습니다.
map.remove (3, "Val3");
map.get (3);
Map.remove (3, "Val33");
map.get (3);
또 다른 유용한 방법 :
코드 사본은 다음과 같습니다.
map.getordefault (42, "찾을 수 없음");
또한지도의 요소를 병합하는 것도 쉽습니다.
코드 사본은 다음과 같습니다.
map.merge (9, "val9", (value, newValue) -> value.concat (newValue));
map.get (9);
map.merge (9, "concat", (value, newValue) -> value.concat (newValue));
map.get (9);
병합은 키 이름이 존재하지 않는 경우 삽입하는 것입니다. 그렇지 않으면 원래 키에 해당하는 값을 병합하여 맵에 다시 삽입하십시오.
9. 날짜 API
Java 8에는 패키지 java.time에 새로운 시간 및 날짜 API 세트가 포함되어 있습니다. 새로운 날짜 API는 오픈 소스 Joda-Time 라이브러리와 유사하지만 다음 예는이 새로운 API의 가장 중요한 부분을 보여줍니다.
시계 시계
클럭 클래스는 현재 날짜와 시간에 액세스하는 방법을 제공합니다. 시계는 시간대에 민감하며 System.currentTimeMillis ()를 사용할 수 있습니다. 특정 시점은 인스턴트 클래스로 표시 될 수 있으며, 이는 오래된 java.util.date 객체를 만드는 데 사용될 수 있습니다.
코드 사본은 다음과 같습니다.
클럭 시계 = clock.systemdefaultzone ();
long millis = clock.millis ();
Instant instant = clock.instant ();
DATE LEGACYDATE = DATE.FROM (Instant);
시간대 시간대
새로운 API에서 시간대는 Zoneid로 표시됩니다. 정적 방법을 사용하여 시간대를 쉽게 얻을 수 있습니다. 시간대는 uts 시간에 대한 시차를 정의하며, 이는 인스턴트 시점 객체와 로컬 날짜 객체를 변환 할 때 매우 중요합니다.
코드 사본은 다음과 같습니다.
System.out.println (ZoneId.getAvailableZoneids ());
// 사용 가능한 모든 시간대 ID를 인쇄합니다
ZoneId Zone1 = Zoneid.of ( "Europe/Berlin");
Zoneid Zone2 = ZoneId.of ( "브라질/이스트");
System.out.println (Zone1.getRules ());
System.out.println (Zone2.GetRules ());
// Zonerules [CurrentStandardOffset =+01 : 00]
// Zonerules [CurrentStandardOffset = -03 : 00]
현지 시간 현지 시간
LocalTime은 오후 10시 또는 17:30:15와 같은 시간대 정보가없는 시간을 정의합니다. 다음 예제는 이전 코드에서 생성 된 시간대를 사용하여 두 개의 로컬 시간을 만듭니다. 그런 다음 시간을 비교하고 두 번 사이의 시차를 몇 시간 및 분으로 계산합니다.
코드 사본은 다음과 같습니다.
localtime now1 = localtime.now (Zone1);
localtime now2 = localtime.now (Zone2);
System.out.println (now1.isbefore (now2));
긴 시간대 = Chronounit.hours.betwen (now1, now2);
긴 순간 간 = Chronounit.minutes.betwne (now1, now2);
System.out.println (시간); // -3
System.out.println (Minutesbetween);
LocalTime은 파싱 시간 문자열을 포함하여 객체 생성을 단순화하기위한 다양한 공장 방법을 제공합니다.
코드 사본은 다음과 같습니다.
localtime late = localtime.of (23, 59, 59);
System.out.println (늦음);
dateTimeFormatter germanformatter =
DateTimeFormatter
.oflocalizedTime (formatstyle.short)
.withLocale (locale.german);
LocalTime leettime = localtime.parse ( "13:37", Germanformatter);
System.out.println (leettime);
현지 날짜
LocalDate는 2014-03-11과 같은 정확한 날짜를 나타냅니다. 이 객체의 값은 불변이며 기본적으로 LocalTime의 가치와 동일합니다. 다음 예제는 날짜 개체에/Moon/Year를 추가하는 방법을 보여줍니다. 또한 이러한 객체는 불변이며 작업은 새 인스턴스를 반환합니다.
코드 사본은 다음과 같습니다.
현지 데이트 오늘 = localdate.now ();
LocalDate Tomorrow = Today.plus (1, chronounit.days);
LocalDate 어제 = 내일 .minusdays (2);
LocalDate IndependeCenday = LocalDate.of (2014, Month.july, 4);
주간 주일의 dayofweek = IndependenceAnday.getDayofweek ();
System.out.println (Dayofweek);
문자열에서 로컬 데이트 유형을 구문 분석하는 것은 LocalTime을 구문 분석하는 것만 큼 간단합니다.
코드 사본은 다음과 같습니다.
dateTimeFormatter germanformatter =
DateTimeFormatter
.ofLocalizedDate (formatstyle.medium)
.withLocale (locale.german);
LocalDate XMAS = LocalDate.Parse ( "24.12.2014", Germanformatter);
System.out.println (Xmas);
LocalDateTime Local DateTime
LocalDateTime은 시간과 날짜를 모두 나타내며, 이는 처음 두 섹션의 내용을 하나의 객체로 병합하는 것과 같습니다. LocalTime 및 LocalDate와 같은 LocalDateTime은 모두 불변입니다. LocalDateTime은 특정 필드에 액세스하는 몇 가지 방법을 제공합니다.
코드 사본은 다음과 같습니다.
LocalDateTime Sylvester = LocalDateTime.of (2014, Month.edecember, 31, 23, 59, 59);
주간 주일의 주차 = sylvester.getdayofweek ();
System.out.println (dayofweek);
월 = sylvester.getmonth ();
System.out.println (월);
Long Minutefday = sylvester.getLong (Chronofield.minute_of_day);
System.out.println (미일); // 1439
시간대 정보를 첨부하기 만하면 순간적 인 객체로 변환 할 수 있습니다.
코드 사본은 다음과 같습니다.
인스턴트 instant = 실베스터
.atzone (ZoneId.SystemDefault ())
.toinstant ();
날짜 regacyDate = date.from (Instant);
System.out.println (LegacyDate); // 12 월 23:59:59 CET 2014
LocalDateTime 서식은 포맷 시간 및 날짜와 동일합니다.
코드 사본은 다음과 같습니다.
dateTimeformatter formatter =
DateTimeFormatter
.ofPattern ( "MMM DD, YYYY -HH : MM");
LocalDateTime Parsed = LocalDateTime.parse ( "2014 년 11 월 3 일 -07:13", Formatter);
문자열 string = formatter.format (구문 분석);
System.out.println (String); // 2014 년 11 월 -07:13
java.text.numberformat과 달리 새 버전의 DateTimeFormatter는 불변이 아니므로 스레드 안전입니다.
시간 및 날짜 형식에 대한 자세한 정보 : http://download.java.net/jdk8/docs/api/java/time/format/datetimeformatter.html
10. 주석 노트
Java 8에서는 여러 주석이 지원됩니다. 먼저 그 의미를 이해하기 위해 예를 살펴 보겠습니다.
먼저, 포장 된 힌트 주석을 정의하여 특정 힌트 주석 세트를 배치하십시오.
코드 사본은 다음과 같습니다.
@interface 힌트 {
힌트 [] value ();
}
@repeatable (hints.class)
@interface 힌트 {
문자열 값 ();
}
Java 8을 사용하면 동일한 유형의 주석을 여러 번 사용할 수 있습니다.
예 1 : 래퍼 클래스를 컨테이너로 사용하여 여러 주석 (오래된 메소드)을 저장합니다.
코드 사본은 다음과 같습니다.
@hints ({ @hint ( "hint1"), @hint ( "hint2")})
클래스 사람 {}
예제 2 : 여러 주석 사용 (새 방법)
코드 사본은 다음과 같습니다.
@hint ( "hint1")
@hint ( "hint2")
클래스 사람 {}
두 번째 예에서는 Java 컴파일러가 @hints 주석을 암시 적으로 정의하여 반사를 사용 하여이 정보를 얻는 데 도움이됩니다.
코드 사본은 다음과 같습니다.
힌트 힌트 = person.class.getAnnotation (hint.class);
System.out.println (힌트);
힌트 hints1 = person.class.getAnnotation (hints.class);
System.out.println (hints1.value (). 길이);
힌트 [] hints2 = person.class.getAntationSyType (hint.class);
System.out.println (hints2.length);
사람 클래스에서 @hints 주석을 정의하지 않더라도 GetAnnotation (hints.class)을 통해 @hints 주석을 얻을 수 있습니다.
또한 Java 8 주석은 두 가지 새로운 대상에 추가되었습니다.
코드 사본은 다음과 같습니다.
@TARGET ({ElementType.Type_Parameter, elementType.type_use})
@Interface myAnnotation {}
그것은 Java 8의 새로운 기능에 관한 것이며, 발견되기를 기다리는 더 많은 기능이 있습니다. JDK 1.8에는 Array.parallelort, StampedLock 및 TompletaLableFuture와 같은 유용한 것들이 많이 있습니다.