ปลดปล่อยพลังของ Java 8: The Ultimate Guide to the Key Features

Feb 16 2023
Java 8 นำเสนอคุณสมบัติใหม่หลายอย่างที่ช่วยให้มีความหลากหลายและยืดหยุ่นมากขึ้น คุณสมบัติ Java 8 ทำให้สามารถตั้งโปรแกรมการทำงานได้
จาวา 8

Java 8นำเสนอคุณสมบัติใหม่หลายอย่างที่ช่วยให้มีความหลากหลายและยืดหยุ่นมากขึ้น คุณสมบัติ Java 8 ทำให้สามารถตั้งโปรแกรมการทำงาน ได้ นี่คือคุณสมบัติหลักบางประการของ Java 8:

  1. การแสดงออกของแลมบ์ดา
  2. อินเทอร์เฟซการทำงาน
  3. สตรีม API
  4. วิธีการเริ่มต้น
  5. การอ้างอิงวิธีการ
  6. ไม่จำเป็น
  7. API วันที่/เวลา

1. การแสดงออกของแลมบ์ดา

จาวา 8 | การแสดงออกของแลมบ์ดา

การใช้แลมบ์ดานิพจน์ทำให้เราสามารถแสดงบล็อกของโค้ดที่สามารถดำเนินการได้ในภายหลัง

นิพจน์แลมบ์ดาใช้เพื่อกำหนดฟังก์ชันนิรนาม ซึ่งสามารถส่งผ่านเป็นอาร์กิวเมนต์ของเมธอดหรือสามารถส่งกลับจากเมธอดได้เช่นเดียวกับอ็อบเจกต์อื่นๆ

ไวยากรณ์นิพจน์แลมบ์ดา:

(parameters) -> { statements };

ตัวอย่าง:

(i) ไม่มีข้อโต้แย้ง

()-> System.out.println("lambda expression with no arguments");

// lambda expression with one argument
(a) -> System.out.println(String.format("Value of a is: %s", a);

// lambda expression with multiple arguments
(a, b) -> a + b;

// also argument type can be provided explicitely
(Integer a, Integer b) -> a + b;

(Integer a, Integer b) -> {  // parentheses needed for multiple statements
    System.out.println(String.format("Returning maximum from %s and %s", a, b));
    return (a > b) a : b;
};

// functional interface, we will see below in detail
interface MaxFinder {
    int findMax(int a, int b);
}

public class LambdaExpressionExample {
    public static void main(String[] args) {
        // return maximum of two numbers using lambda expression
        MaxFinder maxFinder = (a, b) -> (a > b) ? a : b;
        
        System.out.println(maxFinder.findMax(5, 10));
        System.out.println(maxFinder.findMax(15, 5));
    }
}

เอาต์พุต

ตอนนี้ มาดูกันว่าแลมบ์ดานิพจน์ใช้กับforEachลูปได้อย่างไร:

public class LambdaExpressionExample {
  public static void main(String[] args) {
        List<Integer> nums = new ArrayList<>();
        nums.add(1);
        nums.add(2);
        nums.add(3);
        nums.add(4);
        nums.forEach(num -> System.out.println(String.format("Square of %s is %s", num, num * num)));
    }
}

เอาต์พุต

2. อินเทอร์เฟซการทำงาน

จาวา 8 | อินเทอร์เฟซการทำงาน

อินเทอร์เฟซที่มีวิธีการเชิงนามธรรมเพียงวิธีเดียวเรียกว่าอินเทอร์เฟซการทำงานและมีชื่อเป็นSingle Abstract Method Interfaces (SAM Interfaces )

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

Java 8 มีอินเทอร์เฟ ซการทำงานในตัวจำนวนหนึ่ง บางส่วนได้แก่Predicate , Function , ConsumerและSupplier

คุณสามารถดูตัวอย่างง่ายๆ ด้านบนที่เราได้กำหนดอินเทอร์เฟซการทำงานMaxFinder

คำอธิบายประกอบ @FunctionalInterfaceใช้เพื่อแสดงอินเทอร์เฟซการทำงาน

(i) เพรดิเคต

ส่วนต่อประสานเพรดิเคตมีวิธีการทดสอบนามธรรมแบบเดียว( T t)ที่รับอาร์กิวเมนต์เดียวและส่งกลับค่าบูลีน

โดยทั่วไปจะใช้เพื่อกรองค่าหรือทดสอบว่าค่าตรงตามเงื่อนไขหรือไม่

T : ประเภทของอาร์กิวเมนต์อินพุตของเมธอด

นี่คือตัวอย่างการใช้คำกริยา :

Predicate<Integer> isEligibleForVoting = (age) -> age >= 18;
boolean eligible = isEligibleForVoting.test(22); // true

อินเทอร์เฟซ ของฟังก์ชันมีวิธีการนามธรรมแบบเดียวที่ใช้ (T t)ที่รับอาร์กิวเมนต์เดียวและส่งคืนวัตถุ

โดยทั่วไปจะใช้ในการแปลงหรือแมปค่าจากประเภทหนึ่งไปยังอีกประเภทหนึ่ง

นี่คือตัวอย่างการใช้Function :

Function<Integer, Integer> findSquare = (num) -> (num*num);
int square = findSquare.apply(5); // 25

ส่วนต่อประสาน ผู้ใช้มีวิธีการนามธรรมเดียวที่ยอมรับ (T t)ที่รับอาร์กิวเมนต์เดียวและไม่ส่งคืนผลลัพธ์

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

นี่คือตัวอย่างการใช้Consumer :

Consumer<String> printValue = (x) -> System.out.println(x);
printValue.accept("Java 8 features!"); // prints "Java 8 features!"

ส่วนต่อประสานซัพพลายเออร์มีเมธอดนามธรรมเดียว get() ที่ไม่มีอาร์กิวเมนต์และส่งคืนผลลัพธ์

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

นี่คือตัวอย่างการใช้ซัพพลายเออร์:

Supplier<Integer> getRandomInteger = () -> (int) (Math.random() * 500);
int randomInteger = getRandomInteger.get(); // random integer between 0 and 500

public class FunctionalInterfacesExample {

    public static void main(String[] args) {
        // Using Predicate functional interface
        Predicate<Integer> isEligibleForVoting = (age) -> age >= 18;
        boolean eligible = isEligibleForVoting.test(22); // true
        System.out.println(String.format("Eligible for voting: %s", eligible));
        
        // Using Function functional interface
        Function<Integer, Integer> findSquare = (num) -> (num * num);
        int square = findSquare.apply(5); // 25
        System.out.println(String.format("Square of 5: %s", square));
        
        // Using Consumer functional interface
        Consumer<String> printValue = (val) -> System.out.println(val);
        printValue.accept("Java 8 features!"); // prints "Java 8 features!"
        
        // Using Supplier functional interface
        Supplier<Integer> getRandomInteger = () -> (int) (Math.random() * 500);
        int randomInteger = getRandomInteger.get(); // random integer between 0 and 500
        System.out.println(String.format("Random number: %s", randomInteger));
    }

}

เอาต์พุต

3. สตรีม API

จาวา 8 | สตรีม API

Java 8 Stream API เป็นเครื่องมืออันทรงพลังสำหรับการประมวลผลชุดข้อมูล

การใช้งาน การจัดการข้อมูลที่ซับซ้อนของ Stream API สามารถทำได้ด้วยวิธีที่กระชับและชัดเจนมากกว่าที่จะทำได้ด้วยคำสั่งแบบมีเงื่อนไขและลูปแบบดั้งเดิม

สตรีมคือลำดับขององค์ประกอบที่สามารถประมวลผลตามลำดับหรือคู่ขนานกัน

ด้วยความช่วยเหลือของส่วนต่อประสานการทำงานและวิธีการที่เราสามารถสร้างแปลงและประมวลผลสตรีม

สตรีมของคอลเลกชันสามารถสร้างได้โดยใช้เมธอดstream( )

Streams API เป็นส่วนเสริมใหม่ของ Java Collections Framework ที่จัดเตรียมวิธีการที่เปิดเผยในการประมวลผลคอลเล็กชันของออบเจกต์ สตรี มช่วยให้คุณดำเนินการต่างๆ ได้ เช่นการกรองการแมปและการลดคอลเล็กชันของออบเจกต์ด้วย วิธีที่ กระชับและอ่าน ง่าย กว่า for-loop แบบเดิม

Stream API ประกอบด้วยการดำเนินการสามประเภท:

(i) การปฏิบัติการขั้นกลาง:

การดำเนินการระดับกลางใช้เพื่อแปลงหรือกรององค์ประกอบของสตรีม

พวกเขา ส่งคืนสตรีมใหม่ที่การประมวลผลห้องโดยสารเพิ่มเติมโดยการดำเนินการระดับกลางหรือเทอร์มินัล

การดำเนินการขั้นกลางที่ใช้บ่อยที่สุดคือ:

  • filter() : ใช้เพื่อกรองค่าตามเงื่อนไข
  • sorted() : ใช้ในการจัดเรียงองค์ประกอบ
  • ความแตกต่าง () : ใช้เพื่อค้นหาองค์ประกอบที่แตกต่าง
  • map() : ใช้ในการแมปค่าจากประเภทหนึ่งไปยังอีกประเภทหนึ่ง

การดำเนินการเทอร์มินัลใช้เพื่อสร้างผลลัพธ์สุดท้ายจากสตรีม

พวกมันถูกเรียกหลังจากการดำเนินการขั้นกลาง ทั้งหมด ที่ใช้กับสตรีม

การดำเนินการของเทอร์มินัลที่ใช้บ่อยที่สุดคือ:

  • รวบรวม () : ใช้เพื่อส่งคืน ผลลัพธ์ของการดำเนินการขั้นกลาง
  • reduce() : ใช้เพื่อลดองค์ประกอบของกระแสให้เป็นองค์ประกอบเดียว
  • forEach() : ใช้เพื่อวนซ้ำทุกองค์ประกอบในสตรีม
  • count() : ส่งคืนจำนวนองค์ประกอบในสตรีมนี้

การลัดวงจรจะใช้เพื่อสร้างผลลัพธ์ก่อนเวลา โดยไม่ต้องประมวลผลสตรีมทั้งหมด

การทำงานของสตรีม Java 8 ระดับกลางและเทอร์มินัลสามารถลัดวงจรได้

การดำเนินการของเทอร์มินัลที่ใช้บ่อยที่สุดคือ:

  • limit() : ใช้เพื่อส่งคืนสตรีมทันทีที่ถึงค่าจำกัดที่กำหนด
  • anyMatch() : ใช้เพื่อตรวจสอบว่าองค์ประกอบใดของสตรีมนี้ตรงกับเพรดิเคตที่ให้ไว้หรือไม่
  • findFirst() : ส่งคืนตัวเลือกที่อธิบายถึงองค์ประกอบแรกของสตรีมหรือไม่ก็ได้ถ้าสตรีมว่างเปล่า
  • findAny() : คืนค่าตัวเลือกที่อธิบายถึงองค์ประกอบบางอย่างของสตรีม หรือส่งกลับค่าว่างหากสตรีมว่างเปล่า

public class StreamAPIExample {

    public static void main(String[] args) {
        List<Integer> nums = Arrays.asList(3, 1, 4, 2, 6, 8, 5, 7);
        System.out.print("Given numbers list: ");
        nums.forEach(num -> System.out.print(String.format("%s, ", num)));
        System.out.println();
        
        // sort list of numbers
        List<Integer> sortedNums = nums.stream().sorted().collect(Collectors.toList());
        System.out.print("Sorted numbers are: ");
        sortedNums.forEach(num -> System.out.print(String.format("%s, ", num)));
        System.out.println();
        
        // filter all numbers less than 6
        List<Integer> filteredNums = nums.stream()
                .filter(i -> i < 6)
                .collect(Collectors.toList());
        System.out.print("Numbers less then 5 are: ");
        filteredNums.forEach(num -> System.out.print(String.format("%s, ", num)));
        System.out.println();
        
        // odd numbers
        long oddNumsCount = nums.stream()
                .filter(i -> i % 2 == 1).count();
        System.out.println(String.format("Total odd numbers are: %s", oddNumsCount));
        
        // print first 2 even numbers found from list while iterating stream
        System.out.print("first 2 even numbers found from list while iterating stream: ");
        nums.stream()
                .filter(num -> num % 2 == 0)
                .limit(2)
                .forEach(num -> System.out.print(String.format("%s, ", num)));
        System.out.println();
        
        // find squares of numbers
        List<Integer> squares = nums.stream()
                .map(num -> (num * num))
                .collect(Collectors.toList());
        System.out.print("Squares of numbers are: ");
        squares.forEach(square -> System.out.print(String.format("%s, ", square)));
    }

}

เอาต์พุต

ขอบคุณที่อ่าน หวังว่าเรื่องราวนี้จะช่วยคุณในการเรียนรู้คุณสมบัติของ Java 8

โปรดติดตามถ้าคุณชอบบทความ

สมัครสมาชิกเพื่อติดตามบทความที่กำลังจะมาถึง