แนะนำ Aggregate Operations ใน Java 8 กับการเข้าถึง Collection แบบ Stream

บทความเกี่ยวกับ : แนะนำ Aggregate Operations ใน Java 8
มาถึงยุคของการจัดการ Data ใหญ่ๆกันแล้วสินะ
แน่นอนว่า ที่ผ่านมาในโลกของ Java เราคงได้ใช้งาน Collection แบบต่างๆ กันมาแล้ว
ไม่ว่าจะใช้งานอะไรมาบ้าง แต่หลักๆคงหนีไม่พ้นสองข้อ คือ
 จะยัดข้อมูลลงไปยังไง และ จะเอาข้อมูลออกมายังไง

 วันนี้เราจะเน้นอย่างหลังนะครับ คือการ ล้วงข้อมูลใน Collection นั่นเอง
ก่อนอื่นขอแนะนำ Aggregate Operations ที่มาใหม่ใน Java 8 ที่เปลี่ยนรูปแบบการเข้าถึง
 ข้อมูลใน Collection แบบที่เรียกได้ว่าคนที่เคยใช้ For ผ่าน Iterator นี่ต้องทำความเข้าใจเลยทีเดีย

วันนี้จะให้ดูแค่เรื่องของการเขียน Code นะครับ ยังไม่รวมถึงที่มาที่ไปว่า
Aggregate Operations มันดียังไง เร็วกว่ามั๊ย ?  จัดการกับ Data ได้เยอะกว่ามั๊ย ?
มันต่างจาก Iterator แบบเดิมยังไง ?

เก็บคำถามเหล่านี้ไว้ในใจก่อน เพราะถ้าเราไม่ลองใช้เราจะไม่รู้หรอกนะครับว่ามันดียังไง ?
มาเริ่มกันเลย ยกตัวอย่างเรามี  Class ที่จะยัดลงใน Collection ดังนี้

public class Person {
    public enum Sex {
        MALE, FEMALE
    }
    String name;
    LocalDate birthday;
    Sex gender;
    String emailAddress;
    // Getter , Setter อะไรก็ว่ากันไป
}

คือมี Class Person ประกอบด้วย Field (ตัวแปร) ต่างๆตามด้านบน
ยกตัวอย่าง ถ้าเรา Create มาแล้วยัดใส่ใน List ไว้แล้ว และต้องการ วน loop ออกมา
เดิมเราก็เขียน กันแบบนี้ ช่ายมะ

for (Person p : myList) {
    System.out.println(p.getName());
}

 แต่ถ้าเราใช้ Aggregate Operations ใน Java 8 จะเขียนแบบนี้

myList
    .stream()
    .forEach(e -> System.out.println(e.getName());
 
แล้วถ้ามีเงื่อนไขล่ะจะทำยังไง เช่น จะ Print เฉพาะ ผู้ชาย เท่านั้น
แบบเดิมๆ เราก็จะเขียนแบบนี้ (ยากไรก็เช็ค if เพิ่ม)

for (Person p : roster) {
    if (p.getGender() == Person.Sex.MALE) {
        System.out.println(p.getName());
    }
}

แต่ถ้าเป็นแบบ  Aggregate Operations ใน Java 8 จะเขียนแบบนี้
คือแทรก Pipelines ลงไปตามนี้

myList
    .stream()
    .filter(e -> e.getGender() == Person.Sex.MALE)
    .forEach(e -> System.out.println(e.getName()));

ถึงตรงนี้ถ้าเทียบแค่เรื่องการ Coding แล้วคงจะมองว่ามันก็ไม่ได้ต่างกัน
อย่างหลังสำหรับคนที่ไม่คุ้นนี่อาจมองว่าเข้าใจยากกว่าด้วยซ้ำ
มันก็ใช่ แต่อย่าเพิ่งตัดสินครับ
.... เพราะนี่เรายังไม่ได้พูดถึงข้อดีของการทำ stream เลยนะ

 เอาแค่เรื่องการ Coding ต่อละกันนะ ต่อไปนี้คุณต้องชอบแน่ๆ
ถ้าโจทย์มีอยู่ว่าอยากได้ค่าเฉลี่ยของ อายุ เฉพาะ เพศชาย เท่านั้น

ถ้าเขียนแบบเดิมๆ คุณจะเขียนยังไง ?
ก็ไม่รู้สินะก็คงวน loop แล้วใส่ logic ไรเข้าไปตามถนัด

แต่ถ้าเป็นแบบ  Aggregate Operations ใน Java 8 จะเขียนแบบนี้

double average = myList
    .stream()
    .filter(p -> p.getGender() == Person.Sex.MALE)
    .mapToInt(Person::getAge)
    .average()
    .getAsDouble();

 คนอื่นว่าไงไม่รู้แต่ส่วนตัวผมชอบมาก นี่เอาแค่ในเรื่องของ Coding นะ
 เอาที่มันเห็นกันชัดๆ นี่แหละ ไม่รวมข้อดีอื่นๆ ที่ยังไม่ได้พูดถึง

 ปล. นี่แค่น้ำจิ้มนะครับ มันยังทำอะไรได้มากกว่านี้อีกเยอะนัก
อ่านเพิ่มเติมกันได้ที่นี่เลยครับ : http://docs.oracle.com/javase/tutorial/collections/streams/index.html

ความคิดเห็น

โพสต์ยอดนิยมจากบล็อกนี้

Oracle date format จัด format date ให้แสดง พศ และ เดือน ภาษาไทยหรือตามภาษาที่เราเลือก

java -Xms , java -Xmx กำหมด memory ให้ JVM เพื่อป้องกันปัญหา Out of Memory

Java this กับ super การใช้งานคำสั่ง this กับ super ใน ภาษา Java