2016-05-03 20 views
6

Tôi có một giao diện chức năng mở rộng chức năng jdk chuẩn chỉ đơn giản là các loại chung. Bây giờ tôi muốn kết hợp hai chức năng sử dụng andThen được ném biên dịch lỗiGiao diện chức năng mở rộng Java 8 và kết hợp chúng

Error:(25, 25) java: method andThen in interface java.util.function.Function<T,R> cannot be applied to given types;
required: java.util.function.Function<? super ui.instrumentation.api.messaging.Message<R>,? extends V> found: ui.instrumentation.api.transformation.Transformer<T,R> reason: cannot infer type-variable(s) V (argument mismatch; ui.instrumentation.api.transformation.Transformer<T,R> cannot be converted to java.util.function.Function<? super ui.instrumentation.api.messaging.Message<R>,? extends V>)

Đây là đoạn mã mẫu:

public interface Transformer<T,R> extends Function<Message<T>, Message<R>> { 

    static <T, R> Transformer<T, R> combine2(Transformer<T, R> first, Transformer<T, R> second) { 
     return first.andThen(second)); 
    } 
} 

Có cách nào để kết hợp các chức năng mở rộng giao diện chức năng tiêu chuẩn hoặc là có tốt hơn cách để làm điều này?

+2

Tại sao chính xác bạn cần 'cái chức năng combine2', khi 'andThen' không theo nghĩa đen những điều tương tự, cho kiểu lập luận tổng quát hơn' Function'? – Mshnik

+0

Vì vậy, bạn muốn có một hàm nhận 'Message ', chuyển nó đến 'first', nhận được một' Message 'trở lại, sau đó bằng cách nào đó chuyển' Message 'sang' second' mặc dù 'second' cần một 'Thư 'không phải là 'Thư '. – immibis

+2

Đề xuất của tôi: không sử dụng các giao diện mở rộng như vậy. Bạn lưu một vài chữ cái để gõ vào các chi phí không cho phép sử dụng hiện tại của giao diện cơ sở (ở đây 'Chức năng'). Vì vậy, bạn cần phải thực hiện lại mọi thứ, không chỉ 'vàThen', ngay cả các chức năng tầm thường như' Function.identity() 'không thể được sử dụng làm' Biến áp'. Tìm hiểu bài học từ những sai lầm của người khác; mặc dù có chữ ký chức năng giống nhau, bạn không thể sử dụng 'Biến áp ', trong đó yêu cầu 'UnaryOperator >' (ví dụ khác không cho phép kiểu cơ sở 'Hàm')… – Holger

Trả lời

5

Bạn cần cả sửa chữa Generics của bạn, và thay vì sử dụng andThen, mà sẽ chỉ trả lại một Function, bạn sẽ được tốt hơn off nội tuyến lambda mình:

static <T1, T2, T3> Transformer<T1, T3> combine2(Transformer<T1, T2> first, Transformer<T2, T3> second) { 
    return (Message<T1> input) -> second.apply(first.apply(input)); 
} 
5

Vấn đề đầu tiên được rằng andThen mất giá trị trả về của một hàm và làm cho kiểu tham số của hàm tiếp theo, vì vậy bạn cần, như @LouisWasserman giải thích, để chuỗi chúng kết thúc với kiểu đầu ra của một loại khớp với kiểu nhập tiếp theo:

static <T1, T2, T3> Transformer<T1, T3> combine2(Transformer<T1, T2> first, Transformer<T2, T3> second) { 

Vấn đề thứ hai, như ông cũng giải thích, là Function.andThen, mà bạn đang gọi, trả về một Function, không phải là Transformer. Tuy nhiên, lưu ý rằng FunctionTransformer có cùng hình dạng - đầu vào đơn, đầu ra đơn. Do đó, bạn có thể sử dụng một và sau đó điều chỉnh nó với phương pháp khác với tham chiếu phương pháp như sau:

static <T1, T2, T3> Transformer<T1, T3> combine(Transformer<T1, T2> first, Transformer<T2, T3> second) { 
    return first.andThen(second)::apply; 
} 

Bạn không cần tạo hàm để thực hiện việc này. Bạn có thể sử dụng kỹ thuật tương tự gọi Function.andThen() trực tiếp:

Transformer<String,Integer> t1 = ... 
    Transformer<Integer,Double> t2 = ... 
    Transformer<Double,String> t3 = ... 

    Transformer<String,String> t123 = t1.andThen(t2).andThen(t3)::apply; 
+0

Cảm ơn @HankD và @LouisWasserman, đã giúp tôi hiểu rõ hơn. Mục tiêu ban đầu của tôi là kết hợp danh sách nhiều chức năng (máy biến áp trong trường hợp ví dụ) bằng cách nối chúng với vàThen. Nhìn tôi thực sự cần phải ghi đè kết hợp phương pháp cho mỗi biến bổ sung như 'tĩnh này Transformer kết hợp (Transformer đầu tiên, Transformer thứ hai, Transformer thứ ba) { trở first.andThen (thứ hai) .và sau đó (thứ ba) :: áp dụng; } ' Có cách nào tốt hơn để làm điều này tổng hợp hơn nữa danh sách các chức năng? – Raja

+1

Tôi đã cập nhật câu trả lời của mình để cho biết cách bạn có thể làm điều đó –

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