1. นวัตกรรมใน Java 8: การเขียนโปรแกรมเชิงฟังก์ชัน

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

ก่อนที่จะเรียนรู้การเขียนโปรแกรมเชิงฟังก์ชันใน Java เราขอแนะนำให้คุณเข้าใจสามสิ่งนี้ให้ดี:

  1. OOP การสืบทอดและอินเทอร์เฟซ ( ระดับ 1-2 ในภารกิจ Java Core )
  2. การใช้งานเมธอดเริ่ม ต้นในอินเทอร์เฟซ
  3. คลาสภายในและ ไม่ระบุตัว ตน

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

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

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


2. สตรีม I/O: ท่อสตรีม

คุณจำได้ไหมว่ากาลครั้งหนึ่งคุณได้เรียนรู้เกี่ยวกับสตรีม I/O: InputStream, OutputStream, Reader, Writerฯลฯ?

มีคลาสสตรีมที่อ่านข้อมูลจากแหล่งข้อมูลเช่นFileInputSteamและมีสตรีมข้อมูลระดับกลางที่อ่านข้อมูลจากสตรีมอื่น เช่นInputStreamReaderและBufferedReader

สตรีมเหล่านี้สามารถจัดระเบียบเป็นไปป์ไลน์การประมวลผลข้อมูล ตัวอย่างเช่น:

FileInputStream input = new FileInputStream("c:\\readme.txt");
InputStreamReader reader = new InputStreamReader(input);
BufferedReader buff = new BufferedReader(reader);

String text = buff.readLine();

สิ่งสำคัญคือต้องสังเกตว่าในโค้ด 2-3 บรรทัดแรก เรากำลังสร้างห่วงโซ่ของStreamออบเจกต์ เท่านั้น ข้อมูลยังไม่ผ่านท่อ

แต่ทันทีที่เราเรียกใช้buff.readLine()เมธอด สิ่งต่อไปนี้จะเกิดขึ้น:

  1. วัตถุBufferedReaderเรียกread()วิธีการบนInputStreamReaderวัตถุ
  2. วัตถุInputStreamReaderเรียกread()วิธีการบนFileInputStreamวัตถุ
  3. วัตถุFileInputStreamเริ่มอ่านข้อมูลจากไฟล์

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

คอลเลกชันและสตรีม

เริ่มต้นด้วย Java 8 ทำให้สามารถรับสตรีมเพื่ออ่านข้อมูลจากคอลเล็กชัน (และไม่ใช่เฉพาะจากคอลเล็กชันเท่านั้น) แต่นี่ไม่ใช่สิ่งที่น่าสนใจที่สุด มันเป็นไปได้ที่จะสร้างห่วงโซ่ของกระแสข้อมูลที่ซับซ้อนได้อย่างง่ายดายและง่ายดาย และในการทำเช่นนั้น โค้ดที่เคยใช้เวลา 5-10 บรรทัดสามารถเขียนเป็น 1-2 บรรทัดได้แล้ว

ตัวอย่างการค้นหาสตริงที่ยาวที่สุดในรายการสตริง:

ค้นหาสตริงที่ยาวที่สุด
ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");
String max = list.stream().max((s1, s2)-> s1.length()-s2.length()).get();
ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");
Stream<String> stream = list.stream();
Optional<String> optional = stream.max((s1, s2)-> s1.length()-s2.length());
String max = optional.get();

3. Streamอินเทอร์เฟซ

การสนับสนุนแบบขยายสำหรับสตรีมของ Java 8 ถูกนำมาใช้โดยใช้Stream<T>อินเทอร์เฟซ โดยที่Tพารามิเตอร์ประเภทที่ระบุประเภทของข้อมูลที่ถูกส่งผ่านในสตรีม กล่าวอีกนัยหนึ่ง สตรีมไม่ขึ้นกับประเภทของข้อมูลที่ส่งผ่านโดยสิ้นเชิง

หากต้องการรับสตรีมวัตถุจากคอลเล็กชันเพียงเรียกใช้stream()เมธอด รหัสมีลักษณะดังนี้:

Stream<Type> name = collection.stream();
รับสตรีมจากคอลเลกชัน

ในกรณีนี้ คอลเล็กชันจะถือเป็นแหล่งข้อมูลของสตรีม และStream<Type>ออบเจ็กต์จะเป็นเครื่องมือในการรับข้อมูลจากคอลเล็กชันในรูปแบบของสตรีมข้อมูล

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");
Stream<String> stream = list.stream();

อย่างไรก็ตาม คุณสามารถรับสตรีมได้ไม่เพียงแค่จากคอลเลกชันเท่านั้น แต่ยังมาจากอาร์เรย์ด้วย ในการทำเช่นนี้คุณต้องใช้วิธีการ ตัวอย่างเช่น:Arrays.stream()

Stream<Type> name = Arrays.stream(array);
รับสตรีมจากอาร์เรย์

ในกรณีนี้อาร์เรย์จะถือเป็นแหล่งข้อมูลสำหรับสตรีมที่เรียกnameว่า

Integer[] array = {1, 2, 3};
Stream<Integer> stream = Arrays.stream(array);

ไม่มีการย้ายข้อมูลเมื่อStream<Type>สร้างวัตถุ เราเพียงแค่มีวัตถุสตรีมเพื่อเริ่มสร้างสตรีมไปป์ไลน์