JavaRush /จาวาบล็อก /Random-TH /Java 8 ทุกสิ่งที่คุณต้องการ
Roman Beekeeper
ระดับ

Java 8 ทุกสิ่งที่คุณต้องการ

เผยแพร่ในกลุ่ม

บทช่วยสอน Java 8

“ชวายังมีชีวิตอยู่ และผู้คนเริ่มเข้าใจมันแล้ว”
ยินดีต้อนรับสู่การแนะนำ Java 8 ของฉัน บทความนี้จะพาคุณผ่านฟีเจอร์ใหม่ทั้งหมดตั้งแต่ Java 7 ถึง Java 8 ทีละขั้นตอน ด้วยตัวอย่างโค้ดที่ง่ายและรวดเร็ว เราสามารถเรียนรู้วิธีใช้อินเทอร์เฟซเริ่มต้นการอ้างอิงเมธอดและคำอธิบายประกอบที่ทำซ้ำได้ ในตอนท้ายของบทความ เราจะมาทำความรู้จักกับ Stream API
Java 8 สิ่งที่คุณต้องมีคือ 1
ไม่มีการพูดคุยที่ไม่จำเป็น - เพียงแค่เขียนโค้ดและแสดงความคิดเห็น! ซึ่งไปข้างหน้า!

วิธีการเริ่มต้นสำหรับอินเทอร์เฟซ

Java 8 ช่วยให้เราเพิ่มวิธีการที่ไม่ใช่นามธรรม (ที่ใช้งาน) ให้กับอินเทอร์เฟซโดยการเพิ่มdefault. คุณลักษณะนี้เรียกอีกอย่างว่าวิธีการขยาย ด้านล่างนี้เป็นตัวอย่างแรก:
interface Formula {
    double calculate(int a);

    default double sqrt(int a) {
        return Math.sqrt(a);
    }
}
นอกเหนือจากวิธีนามธรรมแล้วcalculateอินเทอร์เฟซFormulaยังกำหนดวิธีการเริ่มต้นsqrtด้วย คลาสที่ใช้อินเทอร์เฟซนี้จำเป็นต้องใช้ไฟล์calculate. วิธีการเริ่มต้นsqrtสามารถใช้ได้ทันที
Formula formula = new Formula() {
    @Override
    public double calculate(int a) {
        return sqrt(a * 100);
    }
};

formula.calculate(100);     // 100.0
formula.sqrt(16);           // 4.0
อินเทอร์เฟซFormulaถูกนำไปใช้เป็นคลาสที่ไม่ระบุชื่อ รหัสซ้ำซ้อน: 6 บรรทัดสำหรับการนำไปใช้sqrt(a * 100)งาน ดังที่เราจะเห็นในหัวข้อถัดไป มีวิธีที่ดีกว่าในการใช้วิธีเดียวใน Java 8

นิพจน์แลมบ์ดา

เริ่มจากตัวอย่างง่ายๆ ของการเรียงลำดับรายการสตริงใน Java เวอร์ชันก่อนหน้า:
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ยอมรับรายการและตัวเปรียบเทียบตามลำดับที่จะเรียงลำดับรายการ คุณสามารถสร้างคลาสเปรียบเทียบที่ไม่ระบุตัวตนและส่งต่อได้ตลอดเวลา แทนที่จะสร้างคลาสที่ไม่ระบุชื่อ ใน Java 8 คุณสามารถเขียนรูปแบบที่สั้นกว่าได้ ซึ่งก็คือนิพจน์แลมบ์ดา
Collections.sort(names, (String a, String b) -> {
    return b.compareTo(a);
});
อย่างที่คุณเห็นโค้ดนั้นสั้นกว่าและอ่านง่ายกว่ามาก แต่สิ่งนี้สามารถทำให้สั้นลงได้:
Collections.sort(names, (String a, String b) -> b.compareTo(a));
สำหรับเนื้อหาที่มีหนึ่งบรรทัด คุณสามารถข้าม{}คำนั้นreturnได้ แต่คุณสามารถทำให้สั้นลงได้:
Collections.sort(names, (a, b) -> b.compareTo(a));
คอมไพเลอร์ Java รู้เกี่ยวกับประเภทอาร์กิวเมนต์ ดังนั้นคุณจึงสามารถข้ามมันได้เช่นกัน มาเจาะลึกลงไปในนิพจน์แลมบ์ดาและทำความเข้าใจว่าสามารถนำมาใช้ได้อย่างไร

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

นิพจน์แลมบ์ดาเหมาะสมกับระบบประเภท Java อย่างไร แลมบ์ดาแต่ละตัวสอดคล้องกับประเภทที่อธิบายไว้ในอินเทอร์เฟซ ดังนั้นอินเทอร์เฟซการทำงานควรมีวิธีนามธรรมเพียงวิธีเดียวเท่านั้น นิพจน์แลมบ์ดาทุกประเภทจะสอดคล้องกับวิธีนามธรรมนี้ เนื่องจากวิธีการเริ่มต้นไม่ใช่นามธรรม คุณจึงมีอิสระที่จะสร้างวิธีการเริ่มต้นในส่วนต่อประสานการทำงานได้ตามต้องการ นอกจากนี้เรายังสามารถใช้อินเทอร์เฟซที่กำหนดเองเป็นนิพจน์แลมบ์ดาได้หากมีวิธีนามธรรมเพียงวิธีเดียวในอินเทอร์เฟซนี้ เพื่อให้เป็นไปตามข้อกำหนดเหล่านี้ คุณต้องเพิ่ม@FucntionalInterfaceคำอธิบายประกอบ คอมไพเลอร์รู้เรื่องนี้และจะส่งข้อยกเว้นหากคุณต้องการให้วิธีนามธรรมมากกว่าหนึ่งวิธี ตัวอย่าง:
@FunctionalInterface
interface Converter<F, T> {
    T convert(F from);
}
Converter<String, Integer> converter = (from) -> Integer.valueOf(from);
Integer converted = converter.convert("123");
System.out.println(converted);    // 123
โปรดทราบว่าโค้ดจะคอมไพล์ด้วยหาก@FunctionalInterfaceละเว้นคำอธิบายประกอบ

วิธีการและการอ้างอิงตัวสร้าง

ตัวอย่างข้างต้นสามารถทำให้เล็กลงได้โดยใช้การอ้างอิงวิธีการ:
Converter<String, Integer> converter = Integer::valueOf;
Integer converted = converter.convert("123");
System.out.println(converted);   // 123
Java 8 อนุญาตให้คุณส่งการอ้างอิงไปยังเมธอดหรือคอนสตรัคเตอร์โดยการเพิ่ม::. ตัวอย่างด้านบนแสดงวิธีที่เราสามารถอ้างอิงวิธีการแบบคงที่ แม้ว่าเราจะสามารถอ้างอิงวิธีการที่ไม่คงที่ได้เช่นกัน:
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"
มาดูกันว่า::มันทำงานอย่างไรกับคอนสตรัคเตอร์ ในการเริ่มต้น เราจะกำหนดคลาสตัวอย่างด้วย Constructor ที่แตกต่างกัน:
class Person {
    String firstName;
    String lastName;

    Person() {}

    Person(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
}
ต่อไป เราจะกำหนดอินเทอร์เฟซสำหรับการสร้างวัตถุใหม่:
interface PersonFactory<P extends Person> {
    P create(String firstName, String lastName);
}
แทนที่จะใช้การสร้างโรงงาน เราจะเชื่อมโยงมันทั้งหมดเข้าด้วยกันด้วย::ความช่วยเหลือจากคอนสตรัคเตอร์:
PersonFactory<Person> personFactory = Person::new;
Person person = personFactory.create("Peter", "Parker");
เราสร้างลิงก์ไปยังตัวสร้างผ่านPerson::new. คอมไพเลอร์ Java จะเลือก Constructor ที่ถูกต้องซึ่งตรงกับลายเซ็นของเมธอดโดยPersonFactory.createอัตโนมัติ ... ยังมีต่อ. น่าเสียดายที่ฉันไม่พบวิธีบันทึกฉบับร่างของบทความ และนี่เป็นเรื่องแปลกจริงๆ และหมดเวลาแปลแล้ว ดังนั้นฉันจะเขียนให้เสร็จในภายหลัง สำหรับทุกคนที่รู้และเข้าใจภาษาอังกฤษ - บทความต้นฉบับ หากคุณมีข้อเสนอแนะในการแก้ไขคำแปล โปรดเขียนด้วยวิธีใดก็ได้ที่คุณสะดวก บัญชี Github ของฉัน
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION