【发布时间】:2021-07-26 13:18:59
【问题描述】:
我的意思是,不要自己写这个:
public interface Func<TInput, TResult>
{
TResult call(TInput target) throws Exception;
}
public interface Action<T>
{
void call(T target) throws Exception;
}
【问题讨论】:
标签: java
我的意思是,不要自己写这个:
public interface Func<TInput, TResult>
{
TResult call(TInput target) throws Exception;
}
public interface Action<T>
{
void call(T target) throws Exception;
}
【问题讨论】:
标签: java
在 Java 8 中,等价物分别是 java.util.function.Function<T, R> 和 java.util.function.Consumer<T> 接口。同样,java.util.function.Predicate<T> 等价于 System.Predicate<T>。如其他地方所述,这些是接口而不是委托。
除此之外:我目前非常依赖以下实用程序类来执行类似 LINQ 的扩展方法:
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;
}
}
与System.Linq.Enumerable.Where<TSource> 和System.Linq.Enumerable.Select<TSource, TResult> 不同,我在这里介绍的类似LINQ 的方法不是惰性的,并且在将结果集合返回给调用者之前会完全遍历源集合。尽管如此,我发现它们对于纯粹的句法目的很有用,如果必要的话可以变得懒惰。给定
class Widget {
public String name() { /* ... */ }
}
可以执行以下操作:
List<Widget> widgets = /* ... */;
Iterable<Widget> filteredWidgets = IterableUtil.where(widgets, w -> w.name().startsWith("some-prefix"));
我更喜欢以下:
List<Widget> widgets = /* ... */;
List<Widget> filteredWidgets = new ArrayList<Widget>();
for (Widget w : widgets) {
if (w.name().startsWith("some-prefix")) {
filteredWidgets.add(w);
}
}
【讨论】:
Function<T, R>和Consumer<T>,还可以找到Java提供的全套常用功能接口here。
【讨论】:
重载的 Func 委托(除了委托与匿名类问题之外)的优雅之处在于它们支持 0 到 16 个参数(Func<TResult>、Func<T, TResult>、Func<T1, T2, TResult> 等)
不幸的是,由于类型擦除,这在 Java 中是不可能的。类不能仅因泛型类型参数而有所不同。
Java 8 现在为 Action<T, T2> 引入了诸如 BiConsumer 之类的名称动物园,并且由于 Java 不允许原始类型参数,BiIntConsumer。不过,“动物园”并不是很大,而且我不知道有哪个图书馆可以扩展它。对于像(int, int) => void 这样的函数类型文字有一个很棒的提议,但没有被采纳。
【讨论】:
Func`1 等。只是 C# 将它们映射到相同的名称。
Action<T, T2> 引入了诸如BiConsumer 之类的名称动物园,并且由于Java 不允许原始类型参数BiIntConsumer。曾经有过类似(int, int) => void 这样的函数类型文字的提议,但没有被采纳。
对于Func<T> 使用:java.util.function.Supplier
http://docs.oracle.com/javase/8/docs/api/java/util/function/Supplier.html
【讨论】:
Supplier 将等价于Func<T>(相对于Func<T1, T2>)而不是Action。 Action 不接受任何参数并且不返回任何结果。 (其他版本的Action 接受不同数量的参数并且不返回结果。)
Func<T> 并错误地将其记住为 Action<T>。哎呀
Action<>的东西:0个输入,0个输出。最好使用.andThen(...) 功能。
Action<>,具有 0 个输入和 0 个输出。但是请记住,在 Java 中,这些只是接口。因此,您可以创建自己的来使用。
Runnable 对应于 Action<>,虽然它不如新的 Java 8 函数式的东西那么漂亮。
你可以像这样使用java.util.Function
Function<Employee, String> f0 = (e) -> e.toString();
但是如果你要使用多个参数(就像 C# Func 一样),那么你已经定义了如下的 FunctionalInterface 版本
@FunctionalInterface
public interface Func2Args<T, T1, R> {
R apply(T t, T1 t1);
}
@FunctionalInterface
public interface Func3Args<T,T1,T2,R> {
R apply(T t, T1 t1, T2 t2);
}
然后你可以使用变量没有参数
Func2Args<Employee,Employee,String> f2 = (e, e2) -> e.toString() +
e2.toString();
Func3Args<Employee,Employee,Employee,String> f3 = (e, e2, e3) ->
e.toString() + e2.toString() + e3.toString();
【讨论】:
这些确实没有等价物。您可以在 Java 中创建匿名内部类,但往往会有特定的接口,而不是像 Func 和 Action 这样的通用接口。
【讨论】:
Java 没有委托的概念。有关解决方法,请参阅A Java Programmer Looks at C# Delegates:
虽然 C# 有一组功能 类似于Java,它增加了几个 新的和有趣的功能。 委派是对待一个人的能力 方法作为一等对象。一个 C# 委托用于Java开发人员的地方 将使用带有单个接口的接口 方法。在本文中,使用 讨论了 C# 中的委托,以及代码 为 Java 代表提供 可以执行类似操作的对象 功能。下载源代码 在这里。
【讨论】:
对于早于 Java 8 的版本
对于 C# 中的方法回调,我是这样使用的:
public void MyMethod(string par1, string par2, Action<int> callback, Action<int, string> callback2)
{
//Async Code
callback.invoke(1);
callback2.invoke(4, "str");
}
并调用它:
utils.MyMethod("par1", "par2", (i) =>
{
//cb result
}, (i, str) =>
{
//cb2 result
});
我用 Java 制作了小的抽象类
package com.example.app.callbacks;
public abstract class Callback1<T> {
public void invoke(T obj) {}
}
package com.example.app.callbacks;
public abstract class Callback2<T, T2> {
public void invoke(T obj, T2 obj2) {}
}
package com.example.app.callbacks;
public abstract class Callback3<T, T2, T3> {
public void invoke(T obj, T2 obj2, T3 obj3) {}
}
...ETC
Java 方法如下:
public void myMethod(String par1, String par2, final Callback1<int> callback, final Callback2<int, String> callback2) {
//Async Code
callback.invoke(1);
callback2.invoke(4, "str");
}
现在在 Java 中调用它时:
utils.myMethod("par1", "par2", new Callback<int>() {
@Override
public void invoke(int obj) {
super.invoke(obj);
//cb result
}
}, new Callback2<int, String>() {
@Override
public void invoke(int obj, String obj2) {
super.invoke(obj, obj2);
//cb2 result
}
});
这也可以通过将回调传递/设置给要调用它们的类来实现,同样的方法也可以用于创建接口:
package com.example.app.interfaces;
public interface MyInterface<T> {
void makeDo(T obj);
void makeAnotherDo();
}
【讨论】:
从Java 8开始,Func和Action可以通过Functional Interface和Lambda Expression来实现。
Functional Interface 是一种只有一个抽象方法的接口。
@FunctionalInterface
interface Drawable {
void Draw();
}
@FunctionalInterface 属性是可选的。同时,C# 和 Java 的 Lambda 表达式概念是相同的。
下面的Java和C#代码是等价的:
class App
{
public static void Main(string[] args)
{
Action action = () => { Console.WriteLine("Printing from App class"); };
action();
}
}
@FunctionalInterface
interface Drawable {
void Draw();
}
public class App {
public static void main(String[] args) throws Exception {
Drawable drawable = ()->System.out.println("Printing from App class");
drawable.Draw();
}
}
在 Java 中,Func 和 Action 被替换为函数式接口。
使用这种接口,Java 不需要特别具有 Func 和 Action 委托类型,因为我们可以创建任何满足 Func 和 Action 的接口(是它的参数和返回类型)。因此,Java 中的代码比 C# 版本要冗长一些。
(本文总结自https://www.byteinthesky.com/tutorials/func-and-action-equivalent-in-java/)
【讨论】:
如果您来自 C# 背景(像我一样)并正在寻找:
public delegate TResult Func<in T1,in T2,out TResult>(T1 arg1, T2 arg2);
看看:
public interface BiFunction<T, U, R>
【讨论】:
这是我的实现,缺少 Action
package x.y.delegate;
public class IAction {
public interface _0 { void execute(); }
public interface _1<T> { void execute(T p); }
public interface _2<T1, T2> { void execute(T1 p1, T2 p2); }
public interface _3<T1, T2, T3> { void execute(T1 p1, T2 p2, T3 p3); }
public interface _4<T1, T2, T3, T4> { void execute(T1 p1, T2 p2, T3 p3, T4 p4); }
public interface _5<T1, T2, T3, T4, T5> { void execute(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5); }
public interface _6<T1, T2, T3, T4, T5, T6> { void execute(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6); }
public interface _7<T1, T2, T3, T4, T5, T6, T7> { void execute(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7); }
public interface _8<T1, T2, T3, T4, T5, T6, T7, T8> { void execute(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8); }
public interface _9<T1, T2, T3, T4, T5, T6, T7, T8, T9> { void execute(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 p9); }
public interface _10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> { void execute(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 p9, T10 p10); }
public interface _11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> { void execute(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 p9, T10 p10, T11 p11); }
public interface _12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> { void execute(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 p9, T10 p10, T11 p11, T12 p12); }
public interface _13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> { void execute(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 p9, T10 p10, T11 p11, T12 p12, T13 p13); }
public interface _14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> { void execute(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 p9, T10 p10, T11 p11, T12 p12, T13 p13, T14 p14); }
public interface _15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> { void execute(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 p9, T10 p10, T11 p11, T12 p12, T13 p13, T14 p14, T15 p15); }
public interface _16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> { void execute(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8, T9 p9, T10 p10, T11 p11, T12 p12, T13 p13, T14 p14, T15 p15, T16 p16); }
}
class DoSomething {
public void doSm(IAction._1 ack, IAction._2 ack2) {
}
}
或者您可以在此链接中找到我的库,其中包括 Action、Func、Predicate 和 Tuple 的定义: https://github.com/ThinhVu/javaext 或https://jitpack.io/#ThinhVu/javaext/1.0.0
【讨论】: