2009-07-26 24 views
60

Tương đương Java của FuncAction là gì?Tương đương Java của Func và hành động

Ý tôi là, thay vì viết này trên của riêng tôi:

public interface Func<TInput, TResult> 
{ 
    TResult call(TInput target) throws Exception; 
} 
public interface Action<T> 
{ 
    void call(T target) throws Exception; 
} 
+0

Xem thêm http://stackoverflow.com/questions/7296606/what-is-the-closes t-thing-java-has-to-net-func-and-action-delegate – nawfal

Trả lời

3

Có thực sự là không có tương đương cho những. Bạn có thể tạo các lớp bên trong vô danh trong Java, nhưng có xu hướng là các giao diện cụ thể hơn là các giao diện chung như Func và Action.

3

Java không có khái niệm về đại biểu. Đối với một cách tiếp cận workaround, vui lòng xem A Java Programmer Looks at C# Delegates:

Trong khi C# có một tập hợp các khả năng tương tự như Java, nó đã chấp nhận vài tính năng mới và thú vị. Ủy quyền là khả năng xử lý phương thức làm đối tượng hạng nhất. Đại diện C# được sử dụng khi các nhà phát triển Java sẽ sử dụng giao diện với một phương thức duy nhất. Trong bài viết này, việc sử dụng các đại biểu trong C# được thảo luận và mã được trình bày cho một đối tượng Java đối tượng có thể thực hiện chức năng tương tự . Tải xuống mã nguồn tại đây.

27

Giao diện Callable tương tự như Func.

Runnable giao diện tương tự như Hành động.

Nói chung, Java sử dụng các lớp bên trong ẩn danh làm thay thế cho các đại biểu C#. Ví dụ đây là cách bạn thêm mã để phản ứng với nút bấm trong GUI:

button.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      ...//code that reacts to the action... 
     } 
}); 
+12

Điều gì phân biệt Func khỏi Có thể gọi, là có quá tải chung cho tối đa 16 đối số (Func , Func , Func , v.v.). OTOH, Callable không có đối số. Hơn nữa, nó là không thể thực hiện quá tải C# vì loại erasure trong generics. –

5

Sự sang trọng của các đại biểu Func quá tải (ngoài các đại biểu vs vấn đề giai cấp vô danh) là họ hỗ trợ 0-16 đối số (, Func<T, TResult>, Func<T1, T2, TResult>, v.v.)

Thật không may, điều này là không thể trong Java do xóa kiểu. Các lớp không thể khác biệt bởi các tham số kiểu generic.

Java 8 giờ mang một vườn thú có tên như BiConsumer cho Action<T, T2> và, bởi vì Java không cho phép đối số kiểu nguyên thủy, BiIntConsumer. "Sở thú", tuy nhiên, không phải là rất lớn, và tôi không nhận thức được một thư viện mở rộng nó. Có một đề xuất tuyệt vời cho các loại chữ chức năng như (int, int) => void nhưng nó không được chấp nhận.

+2

Điều thú vị là ở các cấp độ CLR chỉ khác nhau bởi số tham số chung có tên khác nhau. '' Func'1'' vv Nó chỉ là C# mà ánh xạ những người cùng tên. – CodesInChaos

+0

@CodesInChaos Ahh, rất thú vị. Java quá xấu cũng không làm theo cách này. Btw, Java 8 bây giờ mang đến một sở thú các tên như 'BiConsumer' cho' Action 'và, bởi vì Java không cho phép các tham số kiểu nguyên thủy,' BiIntConsumer'. Đã có một đề xuất cho các kiểu hàm kiểu như '(int, int) => void' nhưng nó không được chấp nhận. –

66

Trong Java 8, tương đương là các giao diện java.util.function.Function<T, R>java.util.function.Consumer<T> tương ứng. Tương tự, java.util.function.Predicate<T> tương đương với System.Predicate<T>. Như đã đề cập ở nơi khác, đây là những giao diện thay vì các đại biểu.

liên quan sang một bên: Tôi hiện đang nghiêng nhiều vào lớp tiện ích sau đây để làm LINQ giống như phương pháp mở rộng thứ:

abstract class IterableUtil { 
    public static <T> Iterable<T> where(Iterable<T> items, Predicate<T> predicate) { 
    ArrayList<T> result = new ArrayList<T>(); 
    for (T item : items) { 
     if (predicate.test(item)) { 
     result.add(item); 
     } 
    } 
    return result; 
    } 

    public static <T, R> Iterable<R> select(Iterable<T> items, Function<T, R> func) { 
    ArrayList<R> result = new ArrayList<R>(); 
    for (T item : items) { 
     result.add(func.apply(item)); 
    } 
    return result; 
    } 
} 

Không giống như System.Linq.Enumerable.Where<TSource>System.Linq.Enumerable.Select<TSource, TResult> các phương pháp LINQ-như tôi trình bày ở đây không phải là lười biếng và hoàn toàn duyệt qua các bộ sưu tập nguồn trước khi trả về bộ sưu tập kết quả cho người gọi. Tuy nhiên, tôi thấy chúng hữu ích cho mục đích hoàn toàn cú pháp và có thể được thực hiện lười biếng nếu cần thiết. Với

class Widget { 
    public String name() { /* ... */ } 
} 

Người ta có thể làm như sau:

List<Widget> widgets = /* ... */; 
Iterable<Widget> filteredWidgets = IterableUtil.where(widgets, w -> w.name().startsWith("some-prefix")); 

Mà tôi thích như sau:

List<Widget> widgets = /* ... */; 
List<Widget> filteredWidgets = new ArrayList<Widget>(); 
for (Widget w : widgets) { 
    if (w.name().startsWith("some-prefix")) { 
    filteredWidgets.add(w); 
    } 
} 
+1

Chúng tôi thực sự cần phải bỏ phiếu cho câu trả lời này vì câu hỏi này là kết quả tìm kiếm số 1 hiện tại cho "Java tương đương với hành động" và bây giờ là năm 2015 vì vậy công cụ Java 8 là cách tốt hơn so với Java trước đây và gần như bắt chước. điểm này. –

+1

Tôi nghĩ bạn có nghĩa là Iterable filtersWidgets = IterableUtil.where (widgets, w -> w.name(). StartsWith ("some-prefix")); – electricalbah

+0

Ngoài 'Function ' và 'Consumer ', bạn có thể tìm thấy tập hợp đầy đủ các giao diện chức năng phổ biến mà Java cung cấp [ở đây] (https://docs.oracle.com/javase/8/docs/api/java /util/function/package-summary.html). – ZenLulz

2

Đối Func<T> sử dụng: java.util.function.Supplier http://docs.oracle.com/javase/8/docs/api/java/util/function/Supplier.html

+0

'Nhà cung cấp' sẽ tương đương với 'Func ' (trái với 'Func ') không phải là 'Hành động'. 'Action' không chấp nhận đối số và không trả về kết quả nào. (Các phiên bản khác của 'Hành động' chấp nhận số lượng đối số khác nhau và không trả về kết quả nào.) – Servy

+0

Có bạn đúng, sai lầm của tôi. Tôi chạy vào bài đăng này bởi vì tôi đang tìm kiếm 'Func 'cho Java và nhầm lẫn nhớ nó là' Action '. Oops –

+0

Câu trả lời là hữu ích cho tôi anyway. Có java cũng có một cái gì đó như 'Action <>': 0 đầu vào, 0 kết quả đầu ra. Tốt nhất với chức năng '.andThen (...)'. –

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