2009-07-26 9 views
60

¿Cuáles son los equivalentes de Java de Func y Action?Los equivalentes de Java de Func y Acción

Es decir, en lugar de escribir esto en mi propia:

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

Ver también http://stackoverflow.com/questions/7296606/what-is-the-closes t-thing-java-has-to-the-net-func-and-action-deletes – nawfal

Respuesta

3

Realmente no hay equivalentes para las personas. Puede crear clases internas anónimas en Java, pero tiende a haber interfaces específicas en lugar de genéricas como Func y Action.

3

Java no tiene el concepto de delegados. Para un enfoque solución, consulte A Java Programmer Looks at C# Delegates:

mientras que C# tiene un conjunto de capacidades similares a Java, que ha añadido varias nuevas e interesantes características. La delegación es la capacidad de tratar un método como un objeto de primera clase. Se utiliza un delegado C# donde los desarrolladores de Java usarían una interfaz con un único método . En este artículo, se discute el uso de delegados en C# y se presenta el código para un objeto Java Delegate que puede realizar una función similar . Descargue el código fuente aquí.

27

Callable interfaz es similar a Func.

Runnable interfaz es similar a Action.

En general, Java usa clases internas anónimas como reemplazo para C# delegados. Por ejemplo, esta es la forma de agregar código para reaccionar a pulsar el botón en la interfaz:

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

Lo que distingue a Func de Callable, es que hay sobrecargas genéricas para hasta 16 argumentos (Func , Func , Func , etc.). OTOH, invocable no tiene argumentos. Además, es imposible implementar las sobrecargas de C# debido a la supresión del tipo en los genéricos. –

5

La elegancia de los delegados Func sobrecargados (además del delegado vs cuestión de clase anónima) es que se apoyan de 0 a 16 argumentos (Func<TResult>, Func<T, TResult>, Func<T1, T2, TResult>, etc.)

Desafortunadamente, esto es imposible en Java debido a la borradura de tipo. Las clases no pueden diferir solo por los parámetros de tipo genérico.

Java 8 ahora trae un zoológico de nombres como BiConsumer para Action<T, T2> y, como Java no permite argumentos de tipo primitivo, BiIntConsumer. El "zoológico", sin embargo, no es muy grande, y no conozco una biblioteca que lo expanda. Hubo una propuesta maravillosa para literales de tipo de función como (int, int) => void pero no fue adoptada.

+2

Curiosamente, en las clases de nivel CLR que difieren solo por el número de parámetros genéricos tienen diferentes nombres. '' Func'1'', etc. Es solo C# que los mapea con el mismo nombre. – CodesInChaos

+0

@CodesInChaos Ahh, muy interesante. Lástima que Java no lo hizo de esta manera también. Por cierto, Java 8 ahora trae un zoológico de nombres como 'BiConsumer' para 'Acción ' y, como Java no permite parámetros de tipo primitivo, 'BiIntConsumer'. Hubo una propuesta de literales de tipo de función como '(int, int) => void' pero no fue adoptado. –

66

En Java 8, los equivalentes son las interfaces java.util.function.Function<T, R> y java.util.function.Consumer<T>, respectivamente. Del mismo modo, java.util.function.Predicate<T> es equivalente a System.Predicate<T>. Como se mencionó en otra parte, estas son interfaces en lugar de delegados.

relacionados Aparte: Actualmente estoy apoyándose en la siguiente clase de utilidad para hacer LINQ como método de extensión cosas:

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; 
    } 
} 

A diferencia de System.Linq.Enumerable.Where<TSource> y System.Linq.Enumerable.Select<TSource, TResult> los métodos LINQ como que presento aquí no son perezosos y recorrer completamente las colecciones de origen antes de devolver las colecciones de resultados a la persona que llama. Aún así, los encuentro útiles con fines puramente sintácticos y podrían ser flojos si fuera necesario. Dada

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

uno puede hacer lo siguiente:

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

que yo prefiero a lo siguiente:

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

Realmente necesitamos votar esta respuesta ya que esta pregunta es el resultado de búsqueda # 1 actual para "Java equivalente de acción" y ahora es 2015, por lo que Java 8 es mucho mejor que lo que Java tenía antes y casi imita lo de .net en este punto. –

+1

Creo que se refería a Iterable filteredWidgets = IterableUtil.where (widgets, w -> w.name(). StartsWith ("some-prefix")); – electricalbah

+0

Además de 'Función ' y 'Consumer ', puede encontrar el conjunto completo de interfaces funcionales comunes que proporciona Java [aquí] (https://docs.oracle.com/javase/8/docs/api/java /util/function/package-summary.html). – ZenLulz

2
+0

'Proveedor' sería equivalente a' Func '(en oposición a 'Func ') no 'Acción'. Una 'Action' no acepta argumentos y no devuelve ningún resultado. (Otras versiones de 'Action' aceptan varios números de argumentos y no devuelven ningún resultado.) – Servy

+0

Sí, tienes razón, error mío. Me encontré con esta publicación porque estaba buscando 'Func ' para Java y la recordaba erróneamente como 'Acción '. Oops –

+0

La respuesta fue útil para mí de todos modos. ¿Java también tiene algo así como 'Acción <>': 0 entradas, 0 salidas. En el mejor de los casos con la funcionalidad '.andThen (...)'. –

Cuestiones relacionadas