2015-10-22 14 views
7

Tôi đang cố làm quen với các hàm lambda. Để bắt đầu, tôi quyết định viết một lớp tiện dụng gọi là TernaryOperator. Vì vậy, câu hỏi đặt ra là tôi đã nhận được ý thức hệ hay tôi thiếu một cái gì đó vì nó phải được thực hiện theo một cách khác?Đây có phải là cách sử dụng giao diện chức năng phù hợp không?

public class TernaryOperator<T, U> implements Function<T, U> { 

    private final Function<T, U> f; 

    public TernaryOperator(Predicate<? super T> condition, 
          Function<? super T, ? extends U> ifTrue, 
          Function<? super T, ? extends U> ifFalse) { 
     this.f = t -> condition.test(t) ? ifTrue.apply(t) : ifFalse.apply(t); 
    } 

    @Override 
    public U apply(T t) { 
     return f.apply(t); 
    } 
} 

tôi thấy việc sử dụng của lớp này như thế này:

Predicate<Object> condition = Objects::isNull; 
Function<Object, Integer> ifTrue = obj -> 0; 
Function<CharSequence, Integer> ifFalse = CharSequence::length; 
Function<String, Integer> safeStringLength = new TernaryOperator<>(condition, ifTrue, ifFalse); 

Và bây giờ tôi có thể tính toán chiều dài bất kỳ chuỗi ngay cả khi nó là một null với oneliner này.

Vì vậy, nếu bạn có bất kỳ ý tưởng nào về cách viết tốt hơn TernaryOperator hoặc nếu bạn cho rằng nó vô ích, vui lòng cho tôi biết.

+3

Mã của bạn hoàn toàn ổn. – Jesper

+3

Điều này phù hợp hơn cho http://codereview.stackexchange.com/ –

Trả lời

6

Không cần triển khai giao diện Function. Nó tốt hơn để viết phương pháp tĩnh trong một số lớp phù hợp thay vì:

public static <T, U> Function<T, U> ternary(Predicate<? super T> condition, 
         Function<? super T, ? extends U> ifTrue, 
         Function<? super T, ? extends U> ifFalse) { 
    return t -> condition.test(t) ? ifTrue.apply(t) : ifFalse.apply(t); 
} 

Và sử dụng như thế này:

Function<String, Integer> safeStringLength = MyClass.ternary(condition, ifTrue, ifFalse); 

Cũng xem xét sử dụng import static cho lớp tiện ích của bạn và viết đơn giản ternary(condition, ifTrue, ifFalse).

Có lẽ phương pháp này có thể hữu ích trong một số trường hợp. Đặc biệt khi bạn có thể sử dụng tham chiếu phương thức. Ví dụ:

Stream.of(strings).map(ternary(String::isEmpty, x -> "none", String::trim))... 
+3

Nhưng hãy tự hỏi liệu 'ternary (String :: isEmpty, x ->" none ", String :: trim)' thực sự tốt hơn so với biểu thức 's -> s.isEmpty()? "none": s.trim() '… – Holger

Các vấn đề liên quan