Từ 1 tới 4 trên tổng số 4 kết quả

Đề tài: [Java 8 - Lambda Expression] Tìm hiểu về Lambda Expression trong Java 8

  1. #1
    Ngày gia nhập
    01 2007
    Nơi ở
    Somewhere I belong
    Bài viết
    168

    Mặc định [Java 8 - Lambda Expression] Tìm hiểu về Lambda Expression trong Java 8

    Chào tất cả anh chị em CViet, lâu lắm mềnh với quay trở lại và vẫn ăn hại như xưa . Nhân dịp sau một năm làm một "doc-er" một "excel pro" quyết định "ủ mưu" cắp đit quay về nghề coder, người ta có nói không có gì hạnh phúc hơn được làm công việc mà mình yêu thích. Khởi động bằng một bài chia sẻ về những hiểu biết một "new feature" trong Java 8 đó là biểu thức Lambda. Mong anh chị em đọc vào góp ý

    Java 8 đã được Oracle ra mắt vào ngày 25/3/2014 với rất nhiều cải tiến. Trong đó đáng chú ý là Java đã chính thức hỗ trợ biểu thức Lambda. Nếu bạn nào đã từng làm việc với C# chắc quá hiểu về biểu thức này rồi nhỉ.

    Click vào hình ảnh để lấy hình ảnh lớn

Tên:		devoxx_java8_1.png
Lần xem:	6
Size:		48.9 KB
ID:		14222

    Trước khi vào bài chúng ta hãy xem một ví dụ một danh sách các số nguyên như sau
    Java Code:
    1. List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
    Vậy thì làm thế nào để duyệt và in ra toàn bộ các số nguyên có trong list? Chắc chắn chúng ta sẽ làm thế này
    Java Code:
    1. for (Integer numer : numbers) {
    2.        System.out.println(numer);
    3. }

    Việc làm này là quá quen thuộc và lặp đi lặp lại một cách rất nhàm chán nhiều lần trong quá trình phát triển các ứng dụng Java.

    Mô tả vào đời thực nó sẽ giống thế này:
    Một ngày cuối tuần đẹp trời bạn quyết định vào bếp phụ vợ nấu ăn và hãy xem xét cuộc đối thoại sau đây
    - Vợ: Anh yêu! Lấy dùm em mấy quả cà chua trong tủ lạnh.
    - Chồng: Ok!
    - Vợ: Cả thịt bò em để trong ngăn đá nữa nhé.
    - Chồng: Yes, honey.
    - Vợ: À còn mấy quả trứng nữa.
    - Chồng: Here you are, honey.
    - Vợ: Còn gì trong tủ lạnh nữa không anh hỳ.
    - Chồng: Còn mấy quả mướt đắng này.
    - Vợ: Lấy nốt dùm em đi.
    - Chồng: ...
    Bạn thấy đoạn hội thoại trên thế nào? Còn tôi thấy nó thật thừa thãi, giống như một đoạn code rác vậy.

    Đoạn hội thoại trên có thể "fix" lại như sau:
    - Vợ: Anh yêu! Lấy dùm em hết đồ ăn trong tủ lạnh ra nhá:
    - Chồng: Ok, honey!
    Wow một đoạn ... code tuyệt phải không =))

    Và Java 8 cũng cung cấp cho bạn một biểu thức tuyệt vời để giải quyết trường hợp như trên.
    Hãy xem lại đoạn code bên trên và thử áp biểu thức Lambda coi
    Một biểu thức Lambda sẽ có hai phần một phần là tham số phần kia là hành vi cần thực hiện và được cách nhau bởi một dấu ->
    Java Code:
    1. numbers.forEach(value -> System.out.println(value));
    Ở đây cúng ta thấy biến value là một tham số còn System.out.println(value) là một hành vi (in dãy số)
    Chúng ta có thể để ý value không cần khai báo kiểu dữ liệu mà bộ biên dịch vẫn có thể hiểu được. Lợi hai chưa?

    Hoặc ta cũng có thể dùng toán tử :: để thực hiện việc này
    Java Code:
    1. numbers.forEach(System.out::println);
    OK! nhìn đoạn code đã trở nên "ngon" và chuyên nghiệp hơn hơn rất nhiều phải không?
    Trước khi đọc tiếp bạn hay thử download bộ JDK 8 và Netbean IDE 8.0 để chạy thử coi.


    Chúng ta hãy tìm hiểu thêm cái gọi là "hành vi" mà tôi đã đề cập bên trên nhé.
    Hãy xét một ví dụ sau:
    Ta cần một phương thức để thực hiện tính tổng các số nguyên trong một List?
    Rất đơn giản là thực hiện một hàm như sau:
    Java Code:
    1.     public int sumAll(List<Integer> numbers) {
    2.         int total = 0;
    3.         for (int number : numbers) {
    4.             total += number;
    5.         }
    6.         return total;
    7.     }

    Vậy cần thêm hai hàm để thực hiện cộng các số lẻ và các số chẵn ???
    Code thêm hai hàm như sau nữa ???
    Java Code:
    1.     public int sumAllOdd(List<Integer> numbers) {
    2.         int total = 0;
    3.         for (int number : numbers) {
    4.             if (number % 2 != 0) {
    5.                 total += number;
    6.             }
    7.         }
    8.         return total;
    9.     }
    10.     public int sumAllEven(List<Integer> numbers) {
    11.         int total = 0;
    12.         for (int number : numbers) {
    13.             if (number % 2 == 0) {
    14.                 total += number;
    15.             }
    16.         }
    17.         return total;
    18.     }

    Ba hàm trên giống hệt nhau khác nhau mỗi biểu thức điều kiện.
    He he chắc bạn cũng đang nghĩ giống tôi hãy thử biểu thức Lambda cho vấn đề này xem
    Java Code:
    1.     public static int sumAllLambda(List<Integer> numbers, Predicate<Integer> p) {
    2.         int total = 0;
    3.         for (int number : numbers) {
    4.             if (p.test(number)) {
    5.                 total += number;
    6.             }
    7.         }
    8.         return total;
    9.     }
    10.    
    11.     public static boolean isPrime() {
    12.         return true;
    13.     }

    Trước khi giải thích hãy thử áp dụng trong hàm main coi
    Gọi hàm để tổng tất cả các số trong list
    Java Code:
    1. sumAllLambda(numbers, n -> true)
    ở đây numebers là list các số nguyên
    n là tham số, true là hành vi và hành vi này luôn đúng cho nên hàm test của interface Predicate là luôn pass.
    Ta có thể thay true bằng các hành vi như kiểm tra số chẵn như sau
    Java Code:
    1. sumAllLambda(numbers, n -> n % 2 == 0)
    hoặc kiểm tra số lẻ
    Java Code:
    1. sumAllLambda(numbers, n -> n % 2 != 0)
    hoặc các số lớn hơn 3
    Java Code:
    1. sumAllLambda(numbers, n -> n > 3 == 0)
    hoặc thậm chí ta cũng có thể viết một hàm kiểm tra số nguyên tố "isPrime" rồi truyền vào hành vi của biểu thức Lambda đều được.
    Java Code:
    1. sumAllLambda(numbers, n -> isPrime(n))

    Ở đây bạn sẽ thắc mắc với mình là interface Predicate là gì? Trong Java 8 chúng ta có những functional interface hỗ trợ cho việc viết biểu thức Lambda
    Trước tiên tôi sẽ giới thiệu về Predicate, Consumer.
    Predicate thường dùng để xác định và kiểm tra một đối tượng theo một số tiêu chí
    Predicate cung cấp cho chúng ta 5 method sau đây (nguồn Java doc)
    Java Code:
    1.     //Returns a predicate which evaluates to true only if this predicate
    2.     //and the provided predicate both evaluate to true.
    3.     and(Predicate<? super T> p)
    4.  
    5.     //Returns a predicate which negates the result of this predicate.
    6.     negate()
    7.  
    8.     //Returns a predicate which evaluates to true if either
    9.     //this predicate or the provided predicate evaluates to true
    10.     or(Predicate<? super T> p)
    11.  
    12.     //Returns true if the input object matches some criteria
    13.     test(T t)
    14.  
    15.     //Returns a predicate that evaluates to true if both or neither
    16.     //of the component predicates evaluate to true
    17.     xor(Predicate<? super T> p)

    Consumer thường được sử dụng để chấp nhận một đối tượng để thực hiện một hành vi nào đấy, consumer cung cấp cho chúng ta 1 method là
    Java Code:
    1.     /**
    2.      * Performs this operation on the given argument.
    3.      *
    4.      * @param t the input argument
    5.      */
    6.     void accept(T t);

    Đọc có vẻ khó hiểu phết nhờ, ví dụ cái nhá.
    Ta xét một bài toán sau: Viết một chương chính bán vé, nếu trẻ em dưới 6 tuổi sẽ được giảm giá 50%
    Ta sẽ khai báo một lớp khách hàng đơn giản như đan rổ như sau:
    Java Code:
    1.     public static class Customer {
    2.         int age = 0;
    3.         float price = 0;
    4.         float discount = 0;
    5.         public Customer(int age, int price, int discount) {
    6.             this.age = age;
    7.             this.price = price;
    8.             this.discount = discount;
    9.         }
    10.        
    11.         public void printTicketPrice() {
    12.             float newPrice = price - discount;
    13.             System.out.println("Ticket price: " + newPrice);
    14.         }
    15.     }

    Ta viết thêm một method sử lý tính tiền vé như sau
    Java Code:
    1.     public static Customer updateTicketPrice(Customer customer,
    2.             Predicate<Customer> predicate,
    3.             Consumer<Customer> consumer) {
    4.  
    5.         //Ở đây ta xử dụng method test của Predicate để kiểm tra dữ liệu đầu vào.
    6.         if (predicate.test(customer)) {
    7.             //Ở đây ta dùng method accept của Consumer để discount giá vé.
    8.             consumer.accept(customer);
    9.         }
    10.         return customer;
    11.     }

    Ta viết một hàm main rồi áp dụng biểu thức Lambda như sau xem
    Java Code:
    1.         int ticketPrice = 50000;
    2.         Customer customer1 = new Customer(27, ticketPrice, 0);
    3.         customer1 = updateTicketPrice(customer1,
    4.                                         //Lambda expression for Predicate interface
    5.                                         customer -> customer.age <= 6,
    6.                                         //Lambda expression for Consumer interface
    7.                                         customer -> customer.discount = ticketPrice/2);
    8.         customer1.printTicketPrice();
    9.        
    10.         Customer customer2 = new Customer(6, ticketPrice, 0);
    11.         customer2 = updateTicketPrice(customer2,
    12.                                         //Lambda expression for Predicate interface
    13.                                         customer -> customer.age <= 6,
    14.                                         //Lambda expression for Consumer interface
    15.                                         customer -> customer.discount = ticketPrice/2);
    16.         customer2.printTicketPrice();
    17.        
    18.         Chạy thử và in ra màn hình bạn sẽ thấy hai kết quả sau:
    Code:
            Ticket price: 50000.0
            Ticket price: 25000.0
    Vậy ta có thể thấy customer2 là một đứa trẻ 6 tuổi và nó được giảm giá 50%

    (Còn tiếp)
    Đã được chỉnh sửa lần cuối bởi iamvtn : 11-04-2014 lúc 07:32 AM.
    In code we trust

  2. #2
    Ngày gia nhập
    12 2011
    Bài viết
    1

    cảm ơn vì bài viết

  3. #3
    Ngày gia nhập
    11 2008
    Bài viết
    15

    bài viết quá hay mà lại bị drop :(

  4. #4
    Ngày gia nhập
    05 2013
    Nơi ở
    HN
    Bài viết
    1

    work like a charm

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn