Java 8 - คู่มือฉบับย่อ

JAVA 8 เป็นฟีเจอร์หลักของการพัฒนาภาษาโปรแกรม JAVA เวอร์ชันเริ่มต้นเปิดตัวเมื่อวันที่ 18 มีนาคม 2014 ด้วยการเปิดตัว Java 8 Java ให้การสนับสนุนสำหรับการเขียนโปรแกรมที่ใช้งานได้เอ็นจิน JavaScript ใหม่ API ใหม่สำหรับการจัดการเวลาวันที่ API การสตรีมใหม่เป็นต้น

คุณสมบัติใหม่

  • Lambda expression - เพิ่มความสามารถในการประมวลผลการทำงานให้กับ Java

  • Method references- การอ้างอิงฟังก์ชันตามชื่อแทนที่จะเรียกใช้โดยตรง ใช้ฟังก์ชันเป็นพารามิเตอร์

  • Default method - อินเทอร์เฟซที่จะใช้วิธีการเริ่มต้น

  • New tools - เพิ่มเครื่องมือคอมไพเลอร์และยูทิลิตี้ใหม่เช่น 'jdeps' เพื่อค้นหาการอ้างอิง

  • Stream API - สตรีม API ใหม่เพื่ออำนวยความสะดวกในการประมวลผลไปป์ไลน์

  • Date Time API - ปรับปรุงวันเวลา API

  • Optional - เน้นแนวทางปฏิบัติที่ดีที่สุดเพื่อจัดการกับค่าว่างอย่างเหมาะสม

  • Nashorn, JavaScript Engine - เอ็นจิ้นที่ใช้ Java เพื่อรันโค้ด JavaScript

พิจารณาข้อมูลโค้ดต่อไปนี้

import java.util.Collections;
import java.util.List;
import java.util.ArrayList;
import java.util.Comparator;

public class Java8Tester {

   public static void main(String args[]) {
   
      List<String> names1 = new ArrayList<String>();
      names1.add("Mahesh ");
      names1.add("Suresh ");
      names1.add("Ramesh ");
      names1.add("Naresh ");
      names1.add("Kalpesh ");
		
      List<String> names2 = new ArrayList<String>();
      names2.add("Mahesh ");
      names2.add("Suresh ");
      names2.add("Ramesh ");
      names2.add("Naresh ");
      names2.add("Kalpesh ");
		
      Java8Tester tester = new Java8Tester();
      System.out.println("Sort using Java 7 syntax: ");
		
      tester.sortUsingJava7(names1);
      System.out.println(names1);
      System.out.println("Sort using Java 8 syntax: ");
		
      tester.sortUsingJava8(names2);
      System.out.println(names2);
   }
   
   //sort using java 7
   private void sortUsingJava7(List<String> names) {   
      Collections.sort(names, new Comparator<String>() {
         @Override
         public int compare(String s1, String s2) {
            return s1.compareTo(s2);
         }
      });
   }
   
   //sort using java 8
   private void sortUsingJava8(List<String> names) {
      Collections.sort(names, (s1, s2) -> s1.compareTo(s2));
   }
}

รันโปรแกรมเพื่อรับผลลัพธ์ต่อไปนี้

Sort using Java 7 syntax:
[ Kalpesh Mahesh Naresh Ramesh Suresh ]
Sort using Java 8 syntax:
[ Kalpesh Mahesh Naresh Ramesh Suresh ]

ที่นี่ sortUsingJava8() method ใช้ฟังก์ชัน sort ที่มีนิพจน์แลมบ์ดาเป็นพารามิเตอร์เพื่อรับเกณฑ์การเรียงลำดับ

การตั้งค่าสภาพแวดล้อมท้องถิ่น

หากคุณต้องการตั้งค่าสภาพแวดล้อมของคุณเองสำหรับภาษาโปรแกรม Java ส่วนนี้จะแนะนำคุณตลอดกระบวนการ โปรดทำตามขั้นตอนด้านล่างเพื่อตั้งค่าสภาพแวดล้อม Java ของคุณ

สามารถดาวน์โหลด Java SE ได้ฟรีจากลิงค์ต่อไปนี้ -

https://www.oracle.com/technetwork/java/javase/downloads/index-jsp-138363.html

คุณดาวน์โหลดเวอร์ชันตามระบบปฏิบัติการของคุณ

ทำตามคำแนะนำเพื่อดาวน์โหลด Java และเรียกใช้ไฟล์ .exeเพื่อติดตั้ง Java บนเครื่องของคุณ เมื่อคุณติดตั้ง Java บนเครื่องของคุณแล้วคุณจะต้องตั้งค่าตัวแปรสภาพแวดล้อมให้ชี้ไปที่ไดเร็กทอรีการติดตั้งที่ถูกต้อง

การตั้งค่าเส้นทางสำหรับ Windows 2000 / XP

สมมติว่าคุณติดตั้ง Java ในไดเร็กทอรี c: \ Program Files \ java \ jdk -

  • คลิกขวาที่ 'My Computer' และเลือก 'Properties'

  • คลิกที่ปุ่ม "ตัวแปรสภาพแวดล้อม" ใต้แท็บ "ขั้นสูง"

  • ตอนนี้เปลี่ยนตัวแปร 'Path' เพื่อให้มีพา ธ ไปยังไฟล์ปฏิบัติการ Java ตัวอย่างเช่นหากเส้นทางถูกตั้งค่าเป็น 'C: \ WINDOWS \ SYSTEM32' ให้เปลี่ยนเส้นทางของคุณเป็นอ่าน 'C: \ WINDOWS \ SYSTEM32; c: \ Program Files \ java \ jdk \ bin'

การตั้งค่าเส้นทางสำหรับ Windows 95/98 / ME

สมมติว่าคุณติดตั้ง Java ในไดเร็กทอรี c: \ Program Files \ java \ jdk -

  • แก้ไขไฟล์ 'C: \ autoexec.bat' และเพิ่มบรรทัดต่อไปนี้ในตอนท้าย -

    SET PATH =% PATH%; C: \ Program Files \ java \ jdk \ bin

การตั้งค่าเส้นทางสำหรับ Linux, UNIX, Solaris, FreeBSD

ควรตั้งค่า PATH ตัวแปรสภาพแวดล้อมให้ชี้ไปที่ตำแหน่งที่ติดตั้งไบนารี Java อ้างถึงเอกสารประกอบเชลล์ของคุณหากคุณมีปัญหาในการดำเนินการนี้

ตัวอย่างเช่นหากคุณใช้ bash เป็นเชลล์คุณจะต้องเพิ่มบรรทัดต่อไปนี้ที่ท้าย '.bashrc: export PATH = / path / to / java: $ PATH'

บรรณาธิการ Java ยอดนิยม

ในการเขียนโปรแกรม Java คุณต้องมีโปรแกรมแก้ไขข้อความ มี IDE ที่ซับซ้อนมากขึ้นในตลาด แต่ในตอนนี้คุณสามารถพิจารณาข้อใดข้อหนึ่งต่อไปนี้ -

  • Notepad - บนเครื่อง Windows คุณสามารถใช้โปรแกรมแก้ไขข้อความง่ายๆเช่น Notepad (แนะนำสำหรับบทช่วยสอนนี้) หรือ TextPad

  • Netbeans- เป็น Java IDE ที่เป็นโอเพ่นซอร์สและฟรี สามารถดาวน์โหลดได้จากhttps://netbeans.org/index.html.

  • Eclipse - นอกจากนี้ยังเป็น Java IDE ที่พัฒนาโดยชุมชนโอเพนซอร์ส Eclipse และสามารถดาวน์โหลดได้จาก https://www.eclipse.org/.

นิพจน์ Lambda ถูกนำมาใช้ใน Java 8 และได้รับการขนานนามว่าเป็นคุณลักษณะที่ใหญ่ที่สุดของ Java 8 นิพจน์ Lambda ช่วยให้การเขียนโปรแกรมเชิงฟังก์ชันง่ายขึ้นและทำให้การพัฒนาง่ายขึ้นมาก

ไวยากรณ์

นิพจน์แลมบ์ดามีลักษณะตามไวยากรณ์ต่อไปนี้

parameter -> expression body

ต่อไปนี้เป็นลักษณะสำคัญของการแสดงออกของแลมบ์ดา

  • Optional type declaration- ไม่จำเป็นต้องประกาศประเภทของพารามิเตอร์ คอมไพเลอร์สามารถอนุมานได้เหมือนกันจากค่าของพารามิเตอร์

  • Optional parenthesis around parameter- ไม่จำเป็นต้องประกาศพารามิเตอร์เดียวในวงเล็บ สำหรับพารามิเตอร์หลายตัวจำเป็นต้องมีวงเล็บ

  • Optional curly braces - ไม่จำเป็นต้องใช้วงเล็บปีกกาในเนื้อหาที่แสดงออกหากเนื้อหามีคำสั่งเดียว

  • Optional return keyword- คอมไพลเลอร์จะส่งคืนค่าโดยอัตโนมัติหากเนื้อหามีนิพจน์เดียวเพื่อส่งคืนค่า ต้องใช้วงเล็บปีกกาเพื่อระบุว่านิพจน์ส่งคืนค่า

ตัวอย่างนิพจน์แลมบ์ดา

สร้างโปรแกรม Java ต่อไปนี้โดยใช้โปรแกรมแก้ไขที่คุณเลือกใน C: \> JAVA

Java8Tester.java

public class Java8Tester {

   public static void main(String args[]) {
      Java8Tester tester = new Java8Tester();
		
      //with type declaration
      MathOperation addition = (int a, int b) -> a + b;
		
      //with out type declaration
      MathOperation subtraction = (a, b) -> a - b;
		
      //with return statement along with curly braces
      MathOperation multiplication = (int a, int b) -> { return a * b; };
		
      //without return statement and without curly braces
      MathOperation division = (int a, int b) -> a / b;
		
      System.out.println("10 + 5 = " + tester.operate(10, 5, addition));
      System.out.println("10 - 5 = " + tester.operate(10, 5, subtraction));
      System.out.println("10 x 5 = " + tester.operate(10, 5, multiplication));
      System.out.println("10 / 5 = " + tester.operate(10, 5, division));
		
      //without parenthesis
      GreetingService greetService1 = message ->
      System.out.println("Hello " + message);
		
      //with parenthesis
      GreetingService greetService2 = (message) ->
      System.out.println("Hello " + message);
		
      greetService1.sayMessage("Mahesh");
      greetService2.sayMessage("Suresh");
   }
	
   interface MathOperation {
      int operation(int a, int b);
   }
	
   interface GreetingService {
      void sayMessage(String message);
   }
	
   private int operate(int a, int b, MathOperation mathOperation) {
      return mathOperation.operation(a, b);
   }
}

ตรวจสอบผลลัพธ์

รวบรวมคลาสโดยใช้ javac คอมไพเลอร์ดังนี้ -

C:\JAVA>javac Java8Tester.java

ตอนนี้รัน Java8Tester ดังนี้ -

C:\JAVA>java Java8Tester

ควรให้ผลลัพธ์ดังต่อไปนี้ -

10 + 5 = 15
10 - 5 = 5
10 x 5 = 50
10 / 5 = 2
Hello Mahesh
Hello Suresh

ต่อไปนี้เป็นประเด็นสำคัญที่ต้องพิจารณาในตัวอย่างข้างต้น

  • นิพจน์แลมบ์ดาถูกใช้เพื่อกำหนดการใช้งานอินเทอร์เฟซการทำงานแบบอินไลน์เป็นหลักกล่าวคืออินเทอร์เฟซที่ใช้วิธีเดียวเท่านั้น ในตัวอย่างข้างต้นเราได้ใช้นิพจน์แลมด้าประเภทต่างๆเพื่อกำหนดวิธีการดำเนินการของอินเทอร์เฟซ MathOperation จากนั้นเราได้กำหนดการใช้งาน sayMessage ของ GreetingService

  • นิพจน์แลมบ์ดาไม่จำเป็นต้องใช้คลาสที่ไม่ระบุชื่อและมอบความสามารถในการเขียนโปรแกรมเชิงฟังก์ชันที่เรียบง่าย แต่ทรงพลังให้กับ Java

ขอบเขต

การใช้นิพจน์แลมบ์ดาคุณสามารถอ้างถึงตัวแปรสุดท้ายหรือตัวแปรสุดท้ายที่มีประสิทธิภาพ (ซึ่งกำหนดเพียงครั้งเดียว) นิพจน์แลมบ์ดาแสดงข้อผิดพลาดในการคอมไพล์ถ้าตัวแปรถูกกำหนดค่าเป็นครั้งที่สอง

ตัวอย่างขอบเขต

สร้างโปรแกรม Java ต่อไปนี้โดยใช้โปรแกรมแก้ไขที่คุณเลือกใน C: \> JAVA

Java8Tester.java

public class Java8Tester {

   final static String salutation = "Hello! ";
   
   public static void main(String args[]) {
      GreetingService greetService1 = message -> 
      System.out.println(salutation + message);
      greetService1.sayMessage("Mahesh");
   }
	
   interface GreetingService {
      void sayMessage(String message);
   }
}

ตรวจสอบผลลัพธ์

รวบรวมคลาสโดยใช้ javac คอมไพเลอร์ดังนี้ -

C:\JAVA>javac Java8Tester.java

ตอนนี้รัน Java8Tester ดังนี้ -

C:\JAVA>java Java8Tester

ควรให้ผลลัพธ์ดังต่อไปนี้ -

Hello! Mahesh

การอ้างอิงวิธีการช่วยชี้ไปที่วิธีการตามชื่อ การอ้างอิงวิธีการอธิบายโดยใช้สัญลักษณ์ "::" การอ้างอิงวิธีการสามารถใช้เพื่อชี้ประเภทของวิธีการต่อไปนี้ -

  • วิธีการคงที่
  • วิธีการอินสแตนซ์
  • ตัวสร้างโดยใช้ตัวดำเนินการใหม่ (TreeSet :: new)

ตัวอย่างการอ้างอิงวิธีการ

สร้างโปรแกรม Java ต่อไปนี้โดยใช้โปรแกรมแก้ไขที่คุณเลือกใน C: \> JAVA

Java8Tester.java

import java.util.List;
import java.util.ArrayList;

public class Java8Tester {

   public static void main(String args[]) {
      List names = new ArrayList();
		
      names.add("Mahesh");
      names.add("Suresh");
      names.add("Ramesh");
      names.add("Naresh");
      names.add("Kalpesh");
		
      names.forEach(System.out::println);
   }
}

ที่นี่เราได้ส่งผ่านเมธอด System.out :: println เป็นการอ้างอิงเมธอดแบบคงที่

ตรวจสอบผลลัพธ์

รวบรวมคลาสโดยใช้ javac คอมไพเลอร์ดังนี้ -

C:\JAVA>javac Java8Tester.java

ตอนนี้รัน Java8Tester ดังนี้ -

C:\JAVA>java Java8Tester

ควรให้ผลลัพธ์ดังต่อไปนี้ -

Mahesh
Suresh
Ramesh
Naresh
Kalpesh

อินเทอร์เฟซการทำงานมีฟังก์ชันเดียวในการจัดแสดง ตัวอย่างเช่นอินเทอร์เฟซที่เทียบเคียงได้โดยใช้เมธอด 'CompareTo' วิธีเดียวใช้เพื่อการเปรียบเทียบ Java 8 ได้กำหนดอินเทอร์เฟซการทำงานจำนวนมากที่จะใช้อย่างกว้างขวางในนิพจน์แลมบ์ดา ต่อไปนี้เป็นรายการอินเตอร์เฟสการทำงานที่กำหนดไว้ในแพ็คเกจ java.util.Function

ซีเนียร์ อินเทอร์เฟซและคำอธิบาย
1

BiConsumer<T,U>

แสดงถึงการดำเนินการที่ยอมรับอาร์กิวเมนต์อินพุตสองรายการและไม่ส่งคืนผลลัพธ์

2

BiFunction<T,U,R>

แสดงถึงฟังก์ชันที่ยอมรับสองอาร์กิวเมนต์และสร้างผลลัพธ์

3

BinaryOperator<T>

แสดงถึงการดำเนินการบนตัวถูกดำเนินการสองตัวที่เป็นชนิดเดียวกันโดยให้ผลลัพธ์เป็นชนิดเดียวกันกับตัวถูกดำเนินการ

4

BiPredicate<T,U>

แสดงเพรดิเคต (ฟังก์ชันที่มีมูลค่าบูลีน) ของสองอาร์กิวเมนต์

5

BooleanSupplier

แสดงถึงซัพพลายเออร์ของผลลัพธ์ที่มีมูลค่าบูลีน

6

Consumer<T>

แสดงถึงการดำเนินการที่ยอมรับอาร์กิวเมนต์อินพุตเดียวและไม่ส่งคืนผลลัพธ์

7

DoubleBinaryOperator

แสดงการดำเนินการกับตัวถูกดำเนินการที่มีมูลค่าสองเท่าและสร้างผลลัพธ์ที่มีมูลค่าสองเท่า

8

DoubleConsumer

แสดงถึงการดำเนินการที่ยอมรับอาร์กิวเมนต์ค่าคู่เดียวและไม่ส่งคืนผลลัพธ์

9

DoubleFunction<R>

แสดงถึงฟังก์ชันที่ยอมรับอาร์กิวเมนต์ที่มีมูลค่าสองเท่าและสร้างผลลัพธ์

10

DoublePredicate

แสดงเพรดิเคต (ฟังก์ชันที่มีมูลค่าบูลีน) ของอาร์กิวเมนต์ที่มีมูลค่าสองเท่า

11

DoubleSupplier

แสดงถึงซัพพลายเออร์ของผลลัพธ์ที่มีมูลค่าสองเท่า

12

DoubleToIntFunction

แสดงถึงฟังก์ชันที่ยอมรับอาร์กิวเมนต์ที่มีมูลค่าสองเท่าและสร้างผลลัพธ์มูลค่า int

13

DoubleToLongFunction

แสดงถึงฟังก์ชันที่ยอมรับอาร์กิวเมนต์ที่มีมูลค่าสองเท่าและสร้างผลลัพธ์ที่มีมูลค่ายาว

14

DoubleUnaryOperator

แสดงถึงการดำเนินการบนตัวถูกดำเนินการที่มีมูลค่าสองเท่าเดียวที่สร้างผลลัพธ์ที่มีมูลค่าสองเท่า

15

Function<T,R>

แสดงถึงฟังก์ชันที่ยอมรับหนึ่งอาร์กิวเมนต์และสร้างผลลัพธ์

16

IntBinaryOperator

แสดงการดำเนินการกับตัวถูกดำเนินการที่มีมูลค่า int สองตัวและสร้างผลลัพธ์ที่มีมูลค่า int

17

IntConsumer

แสดงถึงการดำเนินการที่ยอมรับอาร์กิวเมนต์ int มูลค่าเดียวและไม่ส่งคืนผลลัพธ์

18

IntFunction<R>

แสดงถึงฟังก์ชันที่ยอมรับอาร์กิวเมนต์ int-value และสร้างผลลัพธ์

19

IntPredicate

แสดงเพรดิเคต (ฟังก์ชันที่มีมูลค่าบูลีน) ของอาร์กิวเมนต์ int มูลค่าหนึ่งรายการ

20

IntSupplier

แสดงถึงซัพพลายเออร์ของผลลัพธ์มูลค่า int

21

IntToDoubleFunction

แสดงถึงฟังก์ชันที่ยอมรับอาร์กิวเมนต์ int-value และสร้างผลลัพธ์ที่มีมูลค่าสองเท่า

22

IntToLongFunction

แสดงถึงฟังก์ชันที่ยอมรับอาร์กิวเมนต์ int-value และสร้างผลลัพธ์ที่มีมูลค่ายาว

23

IntUnaryOperator

แสดงถึงการดำเนินการบนตัวถูกดำเนินการ int มูลค่าเดียวที่สร้างผลลัพธ์มูลค่า int

24

LongBinaryOperator

แสดงถึงการดำเนินการกับตัวถูกดำเนินการที่มีมูลค่ายาวสองตัวและสร้างผลลัพธ์ที่มีมูลค่ายาวนาน

25

LongConsumer

แสดงถึงการดำเนินการที่ยอมรับอาร์กิวเมนต์ที่มีค่ายาวเดียวและไม่ส่งคืนผลลัพธ์

26

LongFunction<R>

แสดงถึงฟังก์ชันที่ยอมรับอาร์กิวเมนต์ที่มีค่ายาวและสร้างผลลัพธ์

27

LongPredicate

แสดงเพรดิเคต (ฟังก์ชันที่มีมูลค่าบูลีน) ของอาร์กิวเมนต์ที่มีค่ายาวหนึ่งรายการ

28

LongSupplier

แสดงถึงซัพพลายเออร์ของผลลัพธ์ที่มีมูลค่ายาวนาน

29

LongToDoubleFunction

แสดงถึงฟังก์ชันที่ยอมรับอาร์กิวเมนต์ที่มีมูลค่ายาวและสร้างผลลัพธ์ที่มีมูลค่าสองเท่า

30

LongToIntFunction

แสดงถึงฟังก์ชันที่ยอมรับอาร์กิวเมนต์ที่มีค่ายาวและสร้างผลลัพธ์มูลค่า int

31

LongUnaryOperator

แสดงถึงการดำเนินการกับตัวถูกดำเนินการที่มีมูลค่ายาวเดียวที่สร้างผลลัพธ์ที่มีมูลค่ายาว

32

ObjDoubleConsumer<T>

แสดงถึงการดำเนินการที่ยอมรับอาร์กิวเมนต์ที่มีมูลค่าวัตถุและค่าสองเท่าและไม่ส่งคืนผลลัพธ์

33

ObjIntConsumer<T>

แสดงถึงการดำเนินการที่ยอมรับอาร์กิวเมนต์ที่มีมูลค่าวัตถุและค่า int และไม่ส่งคืนผลลัพธ์

34

ObjLongConsumer<T>

แสดงถึงการดำเนินการที่ยอมรับอาร์กิวเมนต์ที่มีมูลค่าวัตถุและค่ายาวและไม่ส่งคืนผลลัพธ์

35

Predicate<T>

แสดงเพรดิเคต (ฟังก์ชันที่มีมูลค่าบูลีน) ของหนึ่งอาร์กิวเมนต์

36

Supplier<T>

แสดงถึงซัพพลายเออร์ของผลลัพธ์

37

ToDoubleBiFunction<T,U>

แสดงถึงฟังก์ชันที่ยอมรับสองอาร์กิวเมนต์และสร้างผลลัพธ์ที่มีมูลค่าสองเท่า

38

ToDoubleFunction<T>

แสดงถึงฟังก์ชันที่สร้างผลลัพธ์ที่มีมูลค่าสองเท่า

39

ToIntBiFunction<T,U>

แสดงถึงฟังก์ชันที่ยอมรับสองอาร์กิวเมนต์และสร้างผลลัพธ์มูลค่า int

40

ToIntFunction<T>

แสดงถึงฟังก์ชันที่สร้างผลลัพธ์มูลค่า int

41

ToLongBiFunction<T,U>

แสดงถึงฟังก์ชันที่ยอมรับสองอาร์กิวเมนต์และสร้างผลลัพธ์ที่มีมูลค่ายาว

42

ToLongFunction<T>

แสดงถึงฟังก์ชันที่สร้างผลลัพธ์ที่มีมูลค่ายาว

43

UnaryOperator<T>

แสดงถึงการดำเนินการบนตัวถูกดำเนินการเดียวที่สร้างผลลัพธ์ประเภทเดียวกับตัวถูกดำเนินการ

ตัวอย่างส่วนต่อประสานการทำงาน

อินเตอร์เฟซเพียร์ดิเคต <T> เป็นอินเทอร์เฟซที่ใช้งานได้โดยใช้วิธีการทดสอบ (Object) เพื่อส่งคืนค่าบูลีน อินเทอร์เฟซนี้แสดงว่าวัตถุถูกทดสอบว่าเป็นจริงหรือเท็จ

สร้างโปรแกรม Java ต่อไปนี้โดยใช้โปรแกรมแก้ไขที่คุณเลือกใน C: \> JAVA

Java8Tester.java

import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

public class Java8Tester {

   public static void main(String args[]) {
      List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
		
      // Predicate<Integer> predicate = n -> true
      // n is passed as parameter to test method of Predicate interface
      // test method will always return true no matter what value n has.
		
      System.out.println("Print all numbers:");
		
      //pass n as parameter
      eval(list, n->true);
		
      // Predicate<Integer> predicate1 = n -> n%2 == 0
      // n is passed as parameter to test method of Predicate interface
      // test method will return true if n%2 comes to be zero
		
      System.out.println("Print even numbers:");
      eval(list, n-> n%2 == 0 );
		
      // Predicate<Integer> predicate2 = n -> n > 3
      // n is passed as parameter to test method of Predicate interface
      // test method will return true if n is greater than 3.
		
      System.out.println("Print numbers greater than 3:");
      eval(list, n-> n > 3 );
   }
	
   public static void eval(List<Integer> list, Predicate<Integer> predicate) {

      for(Integer n: list) {

         if(predicate.test(n)) {
            System.out.println(n + " ");
         }
      }
   }
}

ที่นี่เราได้ส่งผ่านอินเทอร์เฟซ Predicate ซึ่งใช้อินพุตเดียวและส่งคืนบูลีน

ตรวจสอบผลลัพธ์

รวบรวมคลาสโดยใช้ javac คอมไพเลอร์ดังนี้ -

C:\JAVA>javac Java8Tester.java

ตอนนี้รัน Java8Tester ดังนี้ -

C:\JAVA>java Java8Tester

ควรให้ผลลัพธ์ดังต่อไปนี้ -

Print all numbers:
1
2
3
4
5
6
7
8
9
Print even numbers:
2
4
6
8
Print numbers greater than 3:
4
5
6
7
8
9

Java 8 นำเสนอแนวคิดใหม่ของการใช้วิธีการเริ่มต้นในอินเทอร์เฟซ ความสามารถนี้ถูกเพิ่มสำหรับความเข้ากันได้แบบย้อนหลังเพื่อให้สามารถใช้อินเทอร์เฟซเก่าเพื่อใช้ประโยชน์จากความสามารถในการแสดงออกของแลมบ์ดาของ Java 8

ตัวอย่างเช่นอินเทอร์เฟซ 'List' หรือ 'Collection' ไม่มีการประกาศเมธอด 'forEach' ดังนั้นการเพิ่มวิธีการดังกล่าวจะทำลายการใช้งานกรอบการรวบรวม Java 8 แนะนำวิธีการเริ่มต้นเพื่อให้อินเทอร์เฟซ List / Collection สามารถมีการใช้งานดีฟอลต์สำหรับแต่ละเมธอดและคลาสที่ใช้อินเทอร์เฟซเหล่านี้ไม่จำเป็นต้องใช้แบบเดียวกัน

ไวยากรณ์

public interface vehicle {

   default void print() {
      System.out.println("I am a vehicle!");
   }
}

หลายค่าเริ่มต้น

ด้วยฟังก์ชันดีฟอลต์ในอินเทอร์เฟซมีความเป็นไปได้ที่คลาสจะใช้สองอินเทอร์เฟซด้วยวิธีการเริ่มต้นเดียวกัน โค้ดต่อไปนี้จะอธิบายวิธีแก้ไขความคลุมเครือนี้

public interface vehicle {

   default void print() {
      System.out.println("I am a vehicle!");
   }
}

public interface fourWheeler {

   default void print() {
      System.out.println("I am a four wheeler!");
   }
}

วิธีแก้ปัญหาแรกคือสร้างวิธีการของตัวเองที่แทนที่การใช้งานเริ่มต้น

public class car implements vehicle, fourWheeler {

   public void print() {
      System.out.println("I am a four wheeler car vehicle!");
   }
}

วิธีที่สองคือการเรียกใช้วิธีเริ่มต้นของอินเทอร์เฟซที่ระบุโดยใช้ super

public class car implements vehicle, fourWheeler {

   public void print() {
      vehicle.super.print();
   }
}

วิธีการเริ่มต้นแบบคงที่

อินเทอร์เฟซสามารถมีเมธอดผู้ช่วยแบบคงที่ได้ตั้งแต่ Java 8 เป็นต้นไป

public interface vehicle {

   default void print() {
      System.out.println("I am a vehicle!");
   }
	
   static void blowHorn() {
      System.out.println("Blowing horn!!!");
   }
}

ตัวอย่างวิธีการเริ่มต้น

สร้างโปรแกรม Java ต่อไปนี้โดยใช้โปรแกรมแก้ไขที่คุณเลือกใน C: \> JAVA

Java8Tester.java

public class Java8Tester {

   public static void main(String args[]) {
      Vehicle vehicle = new Car();
      vehicle.print();
   }
}

interface Vehicle {

   default void print() {
      System.out.println("I am a vehicle!");
   }
	
   static void blowHorn() {
      System.out.println("Blowing horn!!!");
   }
}

interface FourWheeler {

   default void print() {
      System.out.println("I am a four wheeler!");
   }
}

class Car implements Vehicle, FourWheeler {

   public void print() {
      Vehicle.super.print();
      FourWheeler.super.print();
      Vehicle.blowHorn();
      System.out.println("I am a car!");
   }
}

ตรวจสอบผลลัพธ์

รวบรวมคลาสโดยใช้ javac คอมไพเลอร์ดังนี้ -

C:\JAVA>javac Java8Tester.java

ตอนนี้รัน Java8Tester ดังนี้ -

C:\JAVA>java Java8Tester

ควรให้ผลลัพธ์ดังต่อไปนี้ -

I am a vehicle!
I am a four wheeler!
Blowing horn!!!
I am a car!

Stream เป็นเลเยอร์นามธรรมใหม่ที่นำมาใช้ใน Java 8 โดยใช้สตรีมคุณสามารถประมวลผลข้อมูลด้วยวิธีการประกาศที่คล้ายกับคำสั่ง SQL ตัวอย่างเช่นพิจารณาคำสั่ง SQL ต่อไปนี้

SELECT max(salary), employee_id, employee_name FROM Employee

นิพจน์ SQL ด้านบนจะส่งคืนรายละเอียดของพนักงานที่ได้รับเงินเดือนสูงสุดโดยอัตโนมัติโดยไม่ต้องคำนวณใด ๆ ในตอนท้ายของนักพัฒนา การใช้เฟรมเวิร์กคอลเลกชันใน Java นักพัฒนาต้องใช้ลูปและทำการตรวจสอบซ้ำ ความกังวลอีกประการหนึ่งคือประสิทธิภาพ เนื่องจากโปรเซสเซอร์แบบมัลติคอร์พร้อมใช้งานอย่างสะดวกนักพัฒนา Java จึงต้องเขียนการประมวลผลโค้ดแบบขนานซึ่งอาจเกิดข้อผิดพลาดได้ง่าย

เพื่อแก้ไขปัญหาดังกล่าว Java 8 ได้นำเสนอแนวคิดของสตรีมที่ช่วยให้นักพัฒนาสามารถประมวลผลข้อมูลได้อย่างเปิดเผยและใช้ประโยชน์จากสถาปัตยกรรมมัลติคอร์โดยไม่จำเป็นต้องเขียนโค้ดเฉพาะใด ๆ

Stream คืออะไร?

สตรีมแสดงลำดับของออบเจ็กต์จากแหล่งที่มาซึ่งสนับสนุนการดำเนินการรวม ต่อไปนี้เป็นลักษณะของสตรีม -

  • Sequence of elements- สตรีมจัดเตรียมชุดขององค์ประกอบที่เฉพาะเจาะจงตามลำดับ สตรีมรับ / คำนวณองค์ประกอบตามความต้องการ มันไม่เคยเก็บองค์ประกอบ

  • Source - สตรีมใช้ทรัพยากรคอลเลกชันอาร์เรย์หรือ I / O เป็นแหล่งอินพุต

  • Aggregate operations - สตรีมรองรับการดำเนินการรวมเช่นตัวกรองแผนที่ จำกัด ลดค้นหาจับคู่และอื่น ๆ

  • Pipelining- การดำเนินการสตรีมส่วนใหญ่จะส่งคืนสตรีมของตัวเองเพื่อให้สามารถส่งผลลัพธ์ได้ การดำเนินการเหล่านี้เรียกว่าการดำเนินการระดับกลางและหน้าที่ของพวกเขาคือรับอินพุตประมวลผลและส่งคืนเอาต์พุตไปยังเป้าหมาย วิธีการรวบรวม () คือการทำงานของเทอร์มินัลซึ่งโดยปกติจะมีอยู่เมื่อสิ้นสุดการดำเนินการวางท่อเพื่อทำเครื่องหมายจุดสิ้นสุดของสตรีม

  • Automatic iterations - การดำเนินการสตรีมจะทำการวนซ้ำภายในองค์ประกอบต้นทางที่ให้มาตรงกันข้ามกับคอลเล็กชันที่ต้องมีการทำซ้ำอย่างชัดเจน

กำลังสร้างสตรีม

ด้วย Java 8 อินเทอร์เฟซ Collection มีสองวิธีในการสร้างสตรีม

  • stream() - ส่งคืนสตรีมตามลำดับโดยพิจารณาจากคอลเล็กชันเป็นแหล่งที่มา

  • parallelStream() - ส่งคืนสตรีมแบบขนานโดยพิจารณาว่าคอลเล็กชันเป็นแหล่งที่มา

List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());

แต่ละ

สตรีมได้จัดเตรียมเมธอดใหม่ 'forEach' เพื่อวนซ้ำแต่ละองค์ประกอบของสตรีม ส่วนรหัสต่อไปนี้แสดงวิธีการพิมพ์ตัวเลขสุ่ม 10 ตัวโดยใช้ forEach

Random random = new Random();
random.ints().limit(10).forEach(System.out::println);

แผนที่

เมธอด 'map' ใช้เพื่อแมปแต่ละองค์ประกอบกับผลลัพธ์ที่สอดคล้องกัน ส่วนรหัสต่อไปนี้จะพิมพ์สี่เหลี่ยมของตัวเลขที่ไม่ซ้ำกันโดยใช้แผนที่

List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);

//get list of unique squares
List<Integer> squaresList = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());

กรอง

วิธี 'ตัวกรอง' ใช้เพื่อกำจัดองค์ประกอบตามเกณฑ์ ส่วนรหัสต่อไปนี้พิมพ์จำนวนสตริงว่างโดยใช้ตัวกรอง

List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");

//get count of empty string
int count = strings.stream().filter(string -> string.isEmpty()).count();

ขีด จำกัด

วิธีการ 'จำกัด ' ใช้เพื่อลดขนาดของสตรีม ส่วนรหัสต่อไปนี้แสดงวิธีการพิมพ์ตัวเลขสุ่ม 10 ตัวโดยใช้ขีด จำกัด

Random random = new Random();
random.ints().limit(10).forEach(System.out::println);

จัดเรียง

วิธี 'เรียงลำดับ' ใช้เพื่อจัดเรียงสตรีม ส่วนรหัสต่อไปนี้แสดงวิธีการพิมพ์ตัวเลขสุ่ม 10 ตัวตามลำดับที่เรียง

Random random = new Random();
random.ints().limit(10).sorted().forEach(System.out::println);

การประมวลผลแบบขนาน

ParallelStream เป็นอีกทางเลือกหนึ่งของสตรีมสำหรับการประมวลผลแบบขนาน ดูที่ส่วนรหัสต่อไปนี้ที่พิมพ์จำนวนสตริงว่างโดยใช้ parallelStream

List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");

//get count of empty string
long count = strings.parallelStream().filter(string -> string.isEmpty()).count();

เป็นเรื่องง่ายมากที่จะสลับระหว่างสตรีมแบบลำดับและแบบขนาน

นักสะสม

Collectors ใช้เพื่อรวมผลลัพธ์ของการประมวลผลองค์ประกอบของสตรีม Collectors สามารถใช้เพื่อส่งคืนรายการหรือสตริง

List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());

System.out.println("Filtered List: " + filtered);
String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(", "));
System.out.println("Merged String: " + mergedString);

สถิติ

ด้วย Java 8 ตัวรวบรวมสถิติจะถูกนำมาใช้เพื่อคำนวณสถิติทั้งหมดเมื่อดำเนินการประมวลผลสตรีม

List numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);

IntSummaryStatistics stats = numbers.stream().mapToInt((x) -> x).summaryStatistics();

System.out.println("Highest number in List : " + stats.getMax());
System.out.println("Lowest number in List : " + stats.getMin());
System.out.println("Sum of all numbers : " + stats.getSum());
System.out.println("Average of all numbers : " + stats.getAverage());

ตัวอย่างสตรีม

สร้างโปรแกรม Java ต่อไปนี้โดยใช้โปรแกรมแก้ไขที่คุณเลือกใน C: \> JAVA

Java8Tester.java

import java.util.ArrayList;
import java.util.Arrays;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.Map;

public class Java8Tester {

   public static void main(String args[]) {
      System.out.println("Using Java 7: ");
		
      // Count empty strings
      List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
      System.out.println("List: " +strings);
      long count = getCountEmptyStringUsingJava7(strings);
		
      System.out.println("Empty Strings: " + count);
      count = getCountLength3UsingJava7(strings);
		
      System.out.println("Strings of length 3: " + count);
		
      //Eliminate empty string
      List<String> filtered = deleteEmptyStringsUsingJava7(strings);
      System.out.println("Filtered List: " + filtered);
		
      //Eliminate empty string and join using comma.
      String mergedString = getMergedStringUsingJava7(strings,", ");
      System.out.println("Merged String: " + mergedString);
      List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
		
      //get list of square of distinct numbers
      List<Integer> squaresList = getSquares(numbers);
      System.out.println("Squares List: " + squaresList);
      List<Integer> integers = Arrays.asList(1,2,13,4,15,6,17,8,19);
		
      System.out.println("List: " +integers);
      System.out.println("Highest number in List : " + getMax(integers));
      System.out.println("Lowest number in List : " + getMin(integers));
      System.out.println("Sum of all numbers : " + getSum(integers));
      System.out.println("Average of all numbers : " + getAverage(integers));
      System.out.println("Random Numbers: ");
		
      //print ten random numbers
      Random random = new Random();
		
      for(int i = 0; i < 10; i++) {
         System.out.println(random.nextInt());
      }
		
      System.out.println("Using Java 8: ");
      System.out.println("List: " +strings);
		
      count = strings.stream().filter(string->string.isEmpty()).count();
      System.out.println("Empty Strings: " + count);
		
      count = strings.stream().filter(string -> string.length() == 3).count();
      System.out.println("Strings of length 3: " + count);
		
      filtered = strings.stream().filter(string ->!string.isEmpty()).collect(Collectors.toList());
      System.out.println("Filtered List: " + filtered);
		
      mergedString = strings.stream().filter(string ->!string.isEmpty()).collect(Collectors.joining(", "));
      System.out.println("Merged String: " + mergedString);
		
      squaresList = numbers.stream().map( i ->i*i).distinct().collect(Collectors.toList());
      System.out.println("Squares List: " + squaresList);
      System.out.println("List: " +integers);
		
      IntSummaryStatistics stats = integers.stream().mapToInt((x) ->x).summaryStatistics();
		
      System.out.println("Highest number in List : " + stats.getMax());
      System.out.println("Lowest number in List : " + stats.getMin());
      System.out.println("Sum of all numbers : " + stats.getSum());
      System.out.println("Average of all numbers : " + stats.getAverage());
      System.out.println("Random Numbers: ");
		
      random.ints().limit(10).sorted().forEach(System.out::println);
		
      //parallel processing
      count = strings.parallelStream().filter(string -> string.isEmpty()).count();
      System.out.println("Empty Strings: " + count);
   }
	
   private static int getCountEmptyStringUsingJava7(List<String> strings) {
      int count = 0;

      for(String string: strings) {
		
         if(string.isEmpty()) {
            count++;
         }
      }
      return count;
   }
	
   private static int getCountLength3UsingJava7(List<String> strings) {
      int count = 0;
		
      for(String string: strings) {
		
         if(string.length() == 3) {
            count++;
         }
      }
      return count;
   }
	
   private static List<String> deleteEmptyStringsUsingJava7(List<String> strings) {
      List<String> filteredList = new ArrayList<String>();
		
      for(String string: strings) {
		
         if(!string.isEmpty()) {
             filteredList.add(string);
         }
      }
      return filteredList;
   }
	
   private static String getMergedStringUsingJava7(List<String> strings, String separator) {
      StringBuilder stringBuilder = new StringBuilder();
		
      for(String string: strings) {
		
         if(!string.isEmpty()) {
            stringBuilder.append(string);
            stringBuilder.append(separator);
         }
      }
      String mergedString = stringBuilder.toString();
      return mergedString.substring(0, mergedString.length()-2);
   }
	
   private static List<Integer> getSquares(List<Integer> numbers) {
      List<Integer> squaresList = new ArrayList<Integer>();
		
      for(Integer number: numbers) {
         Integer square = new Integer(number.intValue() * number.intValue());
			
         if(!squaresList.contains(square)) {
            squaresList.add(square);
         }
      }
      return squaresList;
   }
	
   private static int getMax(List<Integer> numbers) {
      int max = numbers.get(0);
		
      for(int i = 1;i < numbers.size();i++) {
		
         Integer number = numbers.get(i);
			
         if(number.intValue() > max) {
            max = number.intValue();
         }
      }
      return max;
   }
	
   private static int getMin(List<Integer> numbers) {
      int min = numbers.get(0);
		
      for(int i= 1;i < numbers.size();i++) {
         Integer number = numbers.get(i);
		
         if(number.intValue() < min) {
            min = number.intValue();
         }
      }
      return min;
   }
	
   private static int getSum(List numbers) {
      int sum = (int)(numbers.get(0));
		
      for(int i = 1;i < numbers.size();i++) {
         sum += (int)numbers.get(i);
      }
      return sum;
   }
	
   private static int getAverage(List<Integer> numbers) {
      return getSum(numbers) / numbers.size();
   }
}

ตรวจสอบผลลัพธ์

รวบรวมคลาสโดยใช้ javac คอมไพเลอร์ดังนี้ -

C:\JAVA>javac Java8Tester.java

ตอนนี้รัน Java8Tester ดังนี้ -

C:\JAVA>java Java8Tester

ควรให้ผลลัพธ์ดังต่อไปนี้ -

Using Java 7:
List: [abc, , bc, efg, abcd, , jkl]
Empty Strings: 2
Strings of length 3: 3
Filtered List: [abc, bc, efg, abcd, jkl]
Merged String: abc, bc, efg, abcd, jkl
Squares List: [9, 4, 49, 25]
List: [1, 2, 13, 4, 15, 6, 17, 8, 19]
Highest number in List : 19
Lowest number in List : 1
Sum of all numbers : 85
Average of all numbers : 9
Random Numbers:
-1279735475
903418352
-1133928044
-1571118911
628530462
18407523
-881538250
-718932165
270259229
421676854
Using Java 8:
List: [abc, , bc, efg, abcd, , jkl]
Empty Strings: 2
Strings of length 3: 3
Filtered List: [abc, bc, efg, abcd, jkl]
Merged String: abc, bc, efg, abcd, jkl
Squares List: [9, 4, 49, 25]
List: [1, 2, 13, 4, 15, 6, 17, 8, 19]
Highest number in List : 19
Lowest number in List : 1
Sum of all numbers : 85
Average of all numbers : 9.444444444444445
Random Numbers:
-1009474951
-551240647
-2484714
181614550
933444268
1227850416
1579250773
1627454872
1683033687
1798939493
Empty Strings: 2

ทางเลือกคืออ็อบเจ็กต์คอนเทนเนอร์ที่ใช้บรรจุอ็อบเจ็กต์ที่ไม่เป็นค่าว่าง อ็อบเจ็กต์ทางเลือกใช้เพื่อแทนค่าว่างโดยไม่มีค่า คลาสนี้มีวิธีการยูทิลิตี้ต่าง ๆ เพื่ออำนวยความสะดวกให้โค้ดจัดการกับค่าเป็น 'พร้อมใช้งาน' หรือ 'ไม่พร้อมใช้งาน' แทนที่จะตรวจสอบค่าว่าง ได้รับการแนะนำใน Java 8 และคล้ายกับสิ่งที่เป็นทางเลือกใน Guava

การประกาศคลาส

ต่อไปนี้เป็นคำประกาศสำหรับ java.util.Optional<T> ชั้นเรียน -

public final class Optional<T> extends Object

วิธีการเรียน

ซีเนียร์ วิธีการและคำอธิบาย
1

static <T> Optional<T> empty()

ส่งคืนอินสแตนซ์ตัวเลือกที่ว่างเปล่า

2

boolean equals(Object obj)

ระบุว่าวัตถุอื่น "เท่ากับ" หรือไม่ก็ได้หรือไม่

3

Optional<T> filter(Predicate<? super <T> predicate)

หากค่ามีอยู่และค่าตรงกับเพรดิเคตที่กำหนดจะส่งคืนตัวเลือกที่อธิบายค่ามิฉะนั้นจะส่งกลับค่าว่างเป็นตัวเลือก

4

<U> Optional<U> flatMap(Function<? super T,Optional<U>> mapper)

หากมีค่าอยู่จะใช้ฟังก์ชันการแม็ปที่เป็นทางเลือกที่มีให้กับค่านั้นส่งกลับผลลัพธ์นั้นหรือส่งกลับค่าว่างเป็นตัวเลือก

5

T get()

หากมีค่าอยู่ในตัวเลือกนี้ให้ส่งคืนค่ามิฉะนั้นจะแสดง NoSuchElementException

6

int hashCode()

ส่งคืนค่ารหัสแฮชของมูลค่าปัจจุบันถ้ามีหรือ 0 (ศูนย์) ถ้าไม่มีค่าอยู่

7

void ifPresent(Consumer<? super T> consumer)

หากมีค่าอยู่จะเรียกผู้บริโภคที่ระบุด้วยค่ามิฉะนั้นจะไม่ทำอะไรเลย

8

boolean isPresent()

ส่งคืนค่าจริงหากมีค่าเป็นเท็จหรือเป็นเท็จ

9

<U>Optional<U> map(Function<? super T,? extends U> mapper)

หากมีค่าอยู่ให้ใช้ฟังก์ชันการแม็ปที่ให้มาและถ้าผลลัพธ์ไม่ใช่ค่าว่างจะส่งคืนตัวเลือกที่อธิบายผลลัพธ์

10

static <T> Optional<T> of(T value)

ส่งคืนตัวเลือกที่มีค่าปัจจุบันที่ไม่ใช่ค่าว่างที่ระบุ

11

static <T> Optional<T> ofNullable(T value)

ส่งคืนตัวเลือกที่อธิบายถึงค่าที่ระบุถ้าไม่ใช่ค่าว่างมิฉะนั้นจะส่งกลับค่าว่างเป็นตัวเลือก

12

T orElse(T other)

ส่งคืนค่าหากมีหรือส่งกลับค่าอื่น

13

T orElseGet(Supplier<? extends T> other)

ส่งคืนค่าหากมีอยู่มิฉะนั้นจะเรียกใช้อื่นและส่งคืนผลลัพธ์ของการเรียกใช้นั้น

14

<X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier)

ส่งคืนค่าที่มีอยู่หากมีอยู่มิฉะนั้นจะแสดงข้อยกเว้นที่สร้างขึ้นโดยซัพพลายเออร์ที่ระบุ

15

String toString()

ส่งกลับการแสดงสตริงที่ไม่ว่างเปล่าของตัวเลือกนี้ที่เหมาะสำหรับการดีบัก

คลาสนี้สืบทอดวิธีการจากคลาสต่อไปนี้ -

  • java.lang.Object

ตัวอย่างเพิ่มเติม

สร้างโปรแกรม Java ต่อไปนี้โดยใช้โปรแกรมแก้ไขที่คุณเลือกใน C: \> JAVA

Java8Tester.java

import java.util.Optional;

public class Java8Tester {

   public static void main(String args[]) {
      Java8Tester java8Tester = new Java8Tester();
      Integer value1 = null;
      Integer value2 = new Integer(10);
		
      //Optional.ofNullable - allows passed parameter to be null.
      Optional<Integer> a = Optional.ofNullable(value1);
		
      //Optional.of - throws NullPointerException if passed parameter is null
      Optional<Integer> b = Optional.of(value2);
      System.out.println(java8Tester.sum(a,b));
   }
	
   public Integer sum(Optional<Integer> a, Optional<Integer> b) {
      //Optional.isPresent - checks the value is present or not
		
      System.out.println("First parameter is present: " + a.isPresent());
      System.out.println("Second parameter is present: " + b.isPresent());
		
      //Optional.orElse - returns the value if present otherwise returns
      //the default value passed.
      Integer value1 = a.orElse(new Integer(0));
		
      //Optional.get - gets the value, value should be present
      Integer value2 = b.get();
      return value1 + value2;
   }
}

ตรวจสอบผลลัพธ์

รวบรวมคลาสโดยใช้ javac คอมไพเลอร์ดังนี้ -

C:\JAVA>javac Java8Tester.java

ตอนนี้รัน Java8Tester ดังนี้ -

C:\JAVA>java Java8Tester

ควรให้ผลลัพธ์ดังต่อไปนี้ -

First parameter is present: false
Second parameter is present: true
10

ด้วย Java 8, Nashorn ได้นำเอ็นจิ้นจาวาสคริปต์ที่ได้รับการปรับปรุงมาใช้เพื่อแทนที่ Rhino ที่มีอยู่ Nashorn ให้ประสิทธิภาพที่ดีขึ้น 2 ถึง 10 เท่าเนื่องจากรวบรวมรหัสในหน่วยความจำโดยตรงและส่ง bytecode ไปยัง JVM แนชอร์นใช้คุณสมบัติเรียกใช้ไดนามิกซึ่งเปิดตัวใน Java 7 เพื่อปรับปรุงประสิทธิภาพ

jjs

สำหรับ Nashorn engine JAVA 8 ขอแนะนำเครื่องมือบรรทัดคำสั่งใหม่ jjs, เพื่อรันโค้ดจาวาสคริปต์ที่คอนโซล

การตีความไฟล์ js

สร้างและบันทึกไฟล์ sample.js ใน c: \> โฟลเดอร์ JAVA

ตัวอย่าง js

print('Hello World!');

เปิดคอนโซลและใช้คำสั่งต่อไปนี้

C:\JAVA>jjs sample.js

มันจะสร้างผลลัพธ์ต่อไปนี้:

Hello World!

jjs ในโหมดโต้ตอบ

เปิดคอนโซลและใช้คำสั่งต่อไปนี้

C:\JAVA>jjs
jjs> print("Hello, World!")
Hello, World!
jjs> quit()
>>

ผ่านอาร์กิวเมนต์

เปิดคอนโซลและใช้คำสั่งต่อไปนี้

C:\JAVA> jjs -- a b c
jjs> print('letters: ' +arguments.join(", "))
letters: a, b, c
jjs>

เรียก JavaScript จาก Java

การใช้ ScriptEngineManager โค้ด JavaScript สามารถถูกเรียกและตีความใน Java

ตัวอย่าง

สร้างโปรแกรม Java ต่อไปนี้โดยใช้โปรแกรมแก้ไขที่คุณเลือกใน C: \> JAVA

Java8Tester.java

import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;
import javax.script.ScriptException;

public class Java8Tester {

   public static void main(String args[]) {
      ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
      ScriptEngine nashorn = scriptEngineManager.getEngineByName("nashorn");
		
      String name = "Mahesh";
      Integer result = null;
      
      try {
         nashorn.eval("print('" + name + "')");
         result = (Integer) nashorn.eval("10 + 2");
         
      } catch(ScriptException e) {
         System.out.println("Error executing script: "+ e.getMessage());
      }
      System.out.println(result.toString());
   }
}

ตรวจสอบผลลัพธ์

รวบรวมคลาสโดยใช้ javac คอมไพเลอร์ดังนี้ -

C:\JAVA>javac Java8Tester.java

ตอนนี้รัน Java8Tester ดังนี้ -

C:\JAVA>java Java8Tester

ควรให้ผลลัพธ์ดังต่อไปนี้ -

Mahesh
12

เรียก Java จาก JavaScript

ตัวอย่างต่อไปนี้อธิบายวิธีอิมพอร์ตและใช้คลาส Java ในสคริปต์ java

สร้างและบันทึก sample.js ใน c: \> โฟลเดอร์ JAVA

ตัวอย่าง js

var BigDecimal = Java.type('java.math.BigDecimal');

function calculate(amount, percentage) {

   var result = new BigDecimal(amount).multiply(new BigDecimal(percentage)).divide(
      new BigDecimal("100"), 2, BigDecimal.ROUND_HALF_EVEN);
   
   return result.toPlainString();
}
var result = calculate(568000000000000000023,13.9);
print(result);

เปิดคอนโซลและใช้คำสั่งต่อไปนี้

C:\JAVA>jjs sample.js

ควรให้ผลลัพธ์ดังต่อไปนี้ -

78952000000000000003.20

ด้วย Java 8 จะมีการเปิดตัว Date-Time API ใหม่เพื่อให้ครอบคลุมข้อบกพร่องของ API วันที่และเวลาเก่าดังต่อไปนี้

  • Not thread safe- java.util.Date ไม่ปลอดภัยต่อเธรดดังนั้นนักพัฒนาจึงต้องจัดการกับปัญหาการเกิดพร้อมกันในขณะที่ใช้วันที่ API วันที่ - เวลาใหม่ไม่เปลี่ยนรูปและไม่มีเมธอด setter

  • Poor design- วันที่เริ่มต้นเริ่มต้นจากปี 1900 เดือนเริ่มจาก 1 และวันเริ่มจาก 0 ดังนั้นจึงไม่มีความสม่ำเสมอ API เก่ามีวิธีการโดยตรงน้อยกว่าสำหรับการดำเนินการวันที่ API ใหม่มีวิธีการยูทิลิตี้มากมายสำหรับการดำเนินการดังกล่าว

  • Difficult time zone handling- นักพัฒนาต้องเขียนโค้ดจำนวนมากเพื่อจัดการกับปัญหาเขตเวลา API ใหม่ได้รับการพัฒนาโดยคำนึงถึงการออกแบบเฉพาะโดเมน

Java 8 แนะนำวันที่ - เวลา API ใหม่ภายใต้แพ็คเกจ java.time ต่อไปนี้เป็นคลาสสำคัญบางส่วนที่แนะนำในแพ็คเกจ java.time

  • Local - API วันที่และเวลาที่ง่ายขึ้นโดยไม่มีความซับซ้อนในการจัดการเขตเวลา

  • Zoned - API เฉพาะวัน - เวลาเพื่อจัดการกับเขตเวลาต่างๆ

Local Date-Time API

คลาส LocalDate / LocalTime และ LocalDateTime ทำให้การพัฒนาง่ายขึ้นโดยที่ไม่จำเป็นต้องใช้เขตเวลา มาดูกันเลย

สร้างโปรแกรม java ต่อไปนี้โดยใช้ตัวแก้ไขที่คุณเลือกใน C: \> JAVA

Java8Tester.java

import java.time.LocalDate;
import java.time.LocalTime;
import java.time.LocalDateTime;
import java.time.Month;

public class Java8Tester {

   public static void main(String args[]) {
      Java8Tester java8tester = new Java8Tester();
      java8tester.testLocalDateTime();
   }
	
   public void testLocalDateTime() {
      // Get the current date and time
      LocalDateTime currentTime = LocalDateTime.now();
      System.out.println("Current DateTime: " + currentTime);
		
      LocalDate date1 = currentTime.toLocalDate();
      System.out.println("date1: " + date1);
		
      Month month = currentTime.getMonth();
      int day = currentTime.getDayOfMonth();
      int seconds = currentTime.getSecond();
		
      System.out.println("Month: " + month +"day: " + day +"seconds: " + seconds);
		
      LocalDateTime date2 = currentTime.withDayOfMonth(10).withYear(2012);
      System.out.println("date2: " + date2);
		
      //12 december 2014
      LocalDate date3 = LocalDate.of(2014, Month.DECEMBER, 12);
      System.out.println("date3: " + date3);
		
      //22 hour 15 minutes
      LocalTime date4 = LocalTime.of(22, 15);
      System.out.println("date4: " + date4);
		
      //parse a string
      LocalTime date5 = LocalTime.parse("20:15:30");
      System.out.println("date5: " + date5);
   }
}

ตรวจสอบผลลัพธ์

รวบรวมคลาสโดยใช้ javac คอมไพเลอร์ดังนี้ -

C:\JAVA>javac Java8Tester.java

ตอนนี้รัน Java8Tester ดังนี้ -

C:\JAVA>java Java8Tester

ควรให้ผลลัพธ์ดังต่อไปนี้ -

Current DateTime: 2014-12-09T11:00:45.457
date1: 2014-12-09
Month: DECEMBERday: 9seconds: 45
date2: 2012-12-10T11:00:45.457
date3: 2014-12-12
date4: 22:15
date5: 20:15:30

Zoned Date-Time API

Zoned date-time API จะถูกใช้เมื่อต้องพิจารณาเขตเวลา ให้เราเห็นพวกเขาในการดำเนินการ

สร้างโปรแกรม Java ต่อไปนี้โดยใช้โปรแกรมแก้ไขที่คุณเลือกใน C: \> JAVA

Java8Tester.java

import java.time.ZonedDateTime;
import java.time.ZoneId;

public class Java8Tester {

   public static void main(String args[]) {
      Java8Tester java8tester = new Java8Tester();
      java8tester.testZonedDateTime();
   }
	
   public void testZonedDateTime() {
      // Get the current date and time
      ZonedDateTime date1 = ZonedDateTime.parse("2007-12-03T10:15:30+05:30[Asia/Karachi]");
      System.out.println("date1: " + date1);
		
      ZoneId id = ZoneId.of("Europe/Paris");
      System.out.println("ZoneId: " + id);
		
      ZoneId currentZone = ZoneId.systemDefault();
      System.out.println("CurrentZone: " + currentZone);
   }
}

ตรวจสอบผลลัพธ์

รวบรวมคลาสโดยใช้ javac คอมไพเลอร์ดังนี้ -

C:\JAVA>javac Java8Tester.java

ตอนนี้รัน Java8Tester ดังนี้ -

C:\JAVA>java Java8Tester

ควรให้ผลลัพธ์ดังต่อไปนี้ -

date1: 2007-12-03T10:15:30+05:00[Asia/Karachi]
ZoneId: Europe/Paris
CurrentZone: Etc/UTC

Chrono Units Enum

java.time.temporal.ChronoUnit enum ถูกเพิ่มใน Java 8 เพื่อแทนที่ค่าจำนวนเต็มที่ใช้ใน API เก่าเพื่อแทนวันเดือน ฯลฯ ให้เราดูในการดำเนินการ

สร้างโปรแกรม Java ต่อไปนี้โดยใช้โปรแกรมแก้ไขที่คุณเลือกใน C: \> JAVA

Java8Tester.java

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;

public class Java8Tester {

   public static void main(String args[]) {
      Java8Tester java8tester = new Java8Tester();
      java8tester.testChromoUnits();
   }
	
   public void testChromoUnits() {
      //Get the current date
      LocalDate today = LocalDate.now();
      System.out.println("Current date: " + today);
		
      //add 1 week to the current date
      LocalDate nextWeek = today.plus(1, ChronoUnit.WEEKS);
      System.out.println("Next week: " + nextWeek);
		
      //add 1 month to the current date
      LocalDate nextMonth = today.plus(1, ChronoUnit.MONTHS);
      System.out.println("Next month: " + nextMonth);
		
      //add 1 year to the current date
      LocalDate nextYear = today.plus(1, ChronoUnit.YEARS);
      System.out.println("Next year: " + nextYear);
		
      //add 10 years to the current date
      LocalDate nextDecade = today.plus(1, ChronoUnit.DECADES);
      System.out.println("Date after ten year: " + nextDecade);
   }
}

ตรวจสอบผลลัพธ์

รวบรวมคลาสโดยใช้ javac คอมไพเลอร์ดังนี้ -

C:\JAVA>javac Java8Tester.java

ตอนนี้รัน Java8Tester ดังนี้ -

C:\JAVA>java Java8Tester

ควรให้ผลลัพธ์ดังต่อไปนี้ -

Current date: 2014-12-10
Next week: 2014-12-17
Next month: 2015-01-10
Next year: 2015-12-10
Date after ten year: 2024-12-10

ระยะเวลาและระยะเวลา

ด้วย Java 8 จะมีการแนะนำคลาสพิเศษสองคลาสเพื่อจัดการกับความแตกต่างของเวลา

  • Period - เกี่ยวข้องกับระยะเวลาตามวันที่

  • Duration - เกี่ยวข้องกับระยะเวลาตามระยะเวลา

ให้เราเห็นพวกเขาในการดำเนินการ

สร้างโปรแกรม Java ต่อไปนี้โดยใช้โปรแกรมแก้ไขที่คุณเลือกใน C: \> JAVA

Java8Tester.java

import java.time.temporal.ChronoUnit;

import java.time.LocalDate;
import java.time.LocalTime;
import java.time.Duration;
import java.time.Period;

public class Java8Tester {

   public static void main(String args[]) {
      Java8Tester java8tester = new Java8Tester();
      java8tester.testPeriod();
      java8tester.testDuration();
   }
	
   public void testPeriod() {
      //Get the current date
      LocalDate date1 = LocalDate.now();
      System.out.println("Current date: " + date1);
		
      //add 1 month to the current date
      LocalDate date2 = date1.plus(1, ChronoUnit.MONTHS);
      System.out.println("Next month: " + date2);
      
      Period period = Period.between(date2, date1);
      System.out.println("Period: " + period);
   }
	
   public void testDuration() {
      LocalTime time1 = LocalTime.now();
      Duration twoHours = Duration.ofHours(2);
		
      LocalTime time2 = time1.plus(twoHours);
      Duration duration = Duration.between(time1, time2);
		
      System.out.println("Duration: " + duration);
   }
}

ตรวจสอบผลลัพธ์

รวบรวมคลาสโดยใช้ javac คอมไพเลอร์ดังนี้ -

C:\JAVA>javac Java8Tester.java

ตอนนี้รัน Java8Tester ดังนี้ -

C:\JAVA>java Java8Tester

ควรให้ผลลัพธ์ดังต่อไปนี้ -

Current date: 2014-12-10
Next month: 2015-01-10
Period: P-1M
Duration: PT2H

ตัวปรับอุณหภูมิ

TemporalAdjuster ใช้ในการคำนวณวันที่คณิตศาสตร์ ตัวอย่างเช่นรับ "วันเสาร์ที่สองของเดือน" หรือ "วันอังคารหน้า" ให้เราเห็นพวกเขาในการดำเนินการ

สร้างโปรแกรม Java ต่อไปนี้โดยใช้โปรแกรมแก้ไขที่คุณเลือกใน C: \> JAVA

Java8Tester.java

import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
import java.time.DayOfWeek;

public class Java8Tester {

   public static void main(String args[]) {
      Java8Tester java8tester = new Java8Tester();
      java8tester.testAdjusters();
   }
	
   public void testAdjusters() {
      //Get the current date
      LocalDate date1 = LocalDate.now();
      System.out.println("Current date: " + date1);
		
      //get the next tuesday
      LocalDate nextTuesday = date1.with(TemporalAdjusters.next(DayOfWeek.TUESDAY));
      System.out.println("Next Tuesday on : " + nextTuesday);
		
      //get the second saturday of next month
      LocalDate firstInYear = LocalDate.of(date1.getYear(),date1.getMonth(), 1);
      LocalDate secondSaturday = firstInYear.with(TemporalAdjusters.nextOrSame(
         DayOfWeek.SATURDAY)).with(TemporalAdjusters.next(DayOfWeek.SATURDAY));
      System.out.println("Second Saturday on : " + secondSaturday);
   }
}

ตรวจสอบผลลัพธ์

รวบรวมคลาสโดยใช้ javac คอมไพเลอร์ดังนี้ -

C:\JAVA>javac Java8Tester.java

ตอนนี้รัน Java8Tester ดังนี้ -

C:\JAVA>java Java8Tester

ควรให้ผลลัพธ์ดังต่อไปนี้ -

Current date: 2014-12-10
Next Tuesday on : 2014-12-16
Second Saturday on : 2014-12-13

ความเข้ากันได้ย้อนหลัง

วิธีการ toInstant () จะถูกเพิ่มเข้าไปในออบเจ็กต์ Date และ Calendar ดั้งเดิมซึ่งสามารถใช้เพื่อแปลงเป็น Date-Time API ใหม่ได้ ใช้เมธอด ofInstant (Insant, ZoneId) เพื่อรับวัตถุ LocalDateTime หรือ ZonedDateTime ให้เราเห็นพวกเขาในการดำเนินการ

สร้างโปรแกรม Java ต่อไปนี้โดยใช้โปรแกรมแก้ไขที่คุณเลือกใน C: \> JAVA

Java8Tester.java

import java.time.LocalDateTime;
import java.time.ZonedDateTime;

import java.util.Date;

import java.time.Instant;
import java.time.ZoneId;

public class Java8Tester {

   public static void main(String args[]) {
      Java8Tester java8tester = new Java8Tester();
      java8tester.testBackwardCompatability();
   }
	
   public void testBackwardCompatability() {
      //Get the current date
      Date currentDate = new Date();
      System.out.println("Current date: " + currentDate);
		
      //Get the instant of current date in terms of milliseconds
      Instant now = currentDate.toInstant();
      ZoneId currentZone = ZoneId.systemDefault();
		
      LocalDateTime localDateTime = LocalDateTime.ofInstant(now, currentZone);
      System.out.println("Local date: " + localDateTime);
		
      ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(now, currentZone);
      System.out.println("Zoned date: " + zonedDateTime);
   }
}

ตรวจสอบผลลัพธ์

รวบรวมคลาสโดยใช้ javac คอมไพเลอร์ดังนี้ -

C:\JAVA>javac Java8Tester.java

ตอนนี้รัน Java8Tester ดังนี้ -

C:\JAVA>java Java8Tester

ควรให้ผลลัพธ์ดังต่อไปนี้ -

Current date: Wed Dec 10 05:44:06 UTC 2014
Local date: 2014-12-10T05:44:06.635
Zoned date: 2014-12-10T05:44:06.635Z[Etc/UTC]

ด้วย Java 8 ในที่สุด Base64 ก็ถึงกำหนดแล้ว ตอนนี้ Java 8 มีตัวเข้ารหัสและตัวถอดรหัสในตัวสำหรับการเข้ารหัส Base64 ใน Java 8 เราสามารถใช้การเข้ารหัส Base64 ได้สามประเภท

  • Simple- เอาต์พุตถูกจับคู่กับชุดอักขระที่อยู่ใน A-Za-z0-9 + / ตัวเข้ารหัสไม่เพิ่มฟีดบรรทัดใด ๆ ในเอาต์พุตและตัวถอดรหัสจะปฏิเสธอักขระใด ๆ ที่นอกเหนือจาก A-Za-z0-9 + /

  • URL- เอาต์พุตถูกจับคู่กับชุดอักขระที่อยู่ใน A-Za-z0-9 + _ ผลลัพธ์คือ URL และชื่อไฟล์ที่ปลอดภัย

  • MIME- เอาต์พุตถูกจับคู่กับรูปแบบที่เป็นมิตรกับ MIME เอาต์พุตจะแสดงเป็นบรรทัดละไม่เกิน 76 อักขระและใช้การส่งคืนค่าขนส่ง '\ r' ตามด้วยตัวป้อนบรรทัด '\ n' เป็นตัวคั่นบรรทัด ไม่มีตัวคั่นบรรทัดต่อท้ายเอาต์พุตที่เข้ารหัส

ชั้นเรียนที่ซ้อนกัน

ซีเนียร์ คลาสที่ซ้อนกันและคำอธิบาย
1

static class Base64.Decoder

คลาสนี้ใช้ตัวถอดรหัสสำหรับการถอดรหัสข้อมูลไบต์โดยใช้โครงร่างการเข้ารหัส Base64 ตามที่ระบุใน RFC 4648 และ RFC 2045

2

static class Base64.Encoder

คลาสนี้ใช้ตัวเข้ารหัสสำหรับการเข้ารหัสข้อมูลไบต์โดยใช้โครงร่างการเข้ารหัส Base64 ตามที่ระบุใน RFC 4648 และ RFC 2045

วิธีการ

ซีเนียร์ ชื่อวิธีการและคำอธิบาย
1

static Base64.Decoder getDecoder()

ส่งคืน Base64 ตัวถอดรหัสที่ถอดรหัสโดยใช้โครงร่างการเข้ารหัส base64 ชนิดพื้นฐาน

2

static Base64.Encoder getEncoder()

ส่งคืน Base64.Encoder ที่เข้ารหัสโดยใช้โครงร่างการเข้ารหัส base64 ชนิดพื้นฐาน

3

static Base64.Decoder getMimeDecoder()

ส่งคืน Base64 ตัวถอดรหัสที่ถอดรหัสโดยใช้รูปแบบการถอดรหัส base64 ชนิด MIME

4

static Base64.Encoder getMimeEncoder()

ส่งคืน Base64.Encoder ที่เข้ารหัสโดยใช้โครงร่างการเข้ารหัส base64 ชนิด MIME

5

static Base64.Encoder getMimeEncoder(int lineLength, byte[] lineSeparator)

ส่งคืน Base64.Encoder ที่เข้ารหัสโดยใช้โครงร่างการเข้ารหัส base64 ชนิด MIME ที่มีความยาวบรรทัดและตัวคั่นบรรทัดที่ระบุ

6

static Base64.Decoder getUrlDecoder()

ส่งคืน Base64 ตัวถอดรหัสที่ถอดรหัสโดยใช้รูปแบบการเข้ารหัส URL และ Filename safe base64

7

static Base64.Encoder getUrlEncoder()

ส่งคืน Base64.Encoder ที่เข้ารหัสโดยใช้โครงร่างการเข้ารหัสประเภท base64 ของ URL และ Filename ที่ปลอดภัย

วิธีการสืบทอด

คลาสนี้สืบทอดวิธีการจากคลาสต่อไปนี้ -

  • java.lang.Object

ตัวอย่าง Base64

สร้างโปรแกรม Java ต่อไปนี้โดยใช้โปรแกรมแก้ไขที่คุณเลือกโดยพูดว่า C: /> JAVA

Java8Tester.java

import java.util.Base64;
import java.util.UUID;
import java.io.UnsupportedEncodingException;

public class HelloWorld {

   public static void main(String args[]) {

      try {
		
         // Encode using basic encoder
         String base64encodedString = Base64.getEncoder().encodeToString(
            "TutorialsPoint?java8".getBytes("utf-8"));
         System.out.println("Base64 Encoded String (Basic) :" + base64encodedString);
		
         // Decode
         byte[] base64decodedBytes = Base64.getDecoder().decode(base64encodedString);
		
         System.out.println("Original String: " + new String(base64decodedBytes, "utf-8"));
         base64encodedString = Base64.getUrlEncoder().encodeToString(
            "TutorialsPoint?java8".getBytes("utf-8"));
         System.out.println("Base64 Encoded String (URL) :" + base64encodedString);
		
         StringBuilder stringBuilder = new StringBuilder();
		
         for (int i = 0; i < 10; ++i) {
            stringBuilder.append(UUID.randomUUID().toString());
         }
		
         byte[] mimeBytes = stringBuilder.toString().getBytes("utf-8");
         String mimeEncodedString = Base64.getMimeEncoder().encodeToString(mimeBytes);
         System.out.println("Base64 Encoded String (MIME) :" + mimeEncodedString);

      } catch(UnsupportedEncodingException e) {
         System.out.println("Error :" + e.getMessage());
      }
   }
}

ตรวจสอบผลลัพธ์

รวบรวมคลาสโดยใช้ javac คอมไพเลอร์ดังนี้ -

C:\JAVA>javac Java8Tester.java

ตอนนี้รัน Java8Tester ดังนี้ -

C:\JAVA>java Java8Tester

ควรให้ผลลัพธ์ดังต่อไปนี้ -

Base64 Encoded String (Basic) :VHV0b3JpYWxzUG9pbnQ/amF2YTg=
Original String: TutorialsPoint?java8
Base64 Encoded String (URL) :VHV0b3JpYWxzUG9pbnQ_amF2YTg=
Base64 Encoded String (MIME) :YmU3NWY2ODktNGM5YS00ODlmLWI2MTUtZTVkOTk2YzQ1Njk1Y2EwZTg2OTEtMmRiZC00YTQ1LWJl
NTctMTI1MWUwMTk0ZWQyNDE0NDAwYjgtYTYxOS00NDY5LTllYTctNjc1YzE3YWJhZTk1MTQ2MDQz
NDItOTAyOC00ZWI0LThlOTYtZWU5YzcwNWQyYzVhMTQxMWRjYTMtY2MwNi00MzU0LTg0MTgtNGQ1
MDkwYjdiMzg2ZTY0OWU5MmUtZmNkYS00YWEwLTg0MjQtYThiOTQxNDQ2YzhhNTVhYWExZjItNjU2
Mi00YmM4LTk2ZGYtMDE4YmY5ZDZhMjkwMzM3MWUzNDMtMmQ3MS00MDczLWI0Y2UtMTQxODE0MGU5
YjdmYTVlODUxYzItN2NmOS00N2UyLWIyODQtMThlMWVkYTY4M2Q1YjE3YTMyYmItZjllMS00MTFk
LWJiM2UtM2JhYzUxYzI5OWI4