แนะนำ 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

ความคิดเห็น

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

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

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

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