如何将 lambda 类型强制为特定类型?
How to force lambda type to a specific one?
假设我有一个带有这样签名的函数:
public static <T> List<Future<T>> invokeAll(Stream<Callable<T>> tasks) {
... submit given tasks using executor ...
}
我有一个数据流,应该 "wrapped" 成为可调用的并传递给这个函数。像下面这样的简单映射不起作用:
Stream<String> ids = Stream.of("1", "2", "3");
invokeAll(ids.map((id) -> {
// Do a long computation with given ID...
return Boolean.TRUE; // Compilation error: Type mismatch: cannot convert from Boolean to Callable<Object>
}));
一个解决方案是 return lambda 即 returns lambda:
invokeAll(ids.map((id) -> {
return () -> {
// Do a long computation with given ID...
return Boolean.TRUE;
};
}));
另一个(在某种程度上等效)是使用辅助函数:
public static <T> Callable<T> createCallable(T id) {
return () -> {
return id;
};
}
invokeAll(ids.map(ThisClass::createCallable));
但也许有更好/更短的方法来做同样的事情?例如。以某种方式告诉编译器它需要创建一个 return 给定值的 Callable
:
invokeAll(ids.map((Function<String, Callable<Boolean>>) (id) -> {
// Do a long computation with given ID
return Boolean.TRUE;
}));
感谢任何建议。
让我们暂时忽略 lambda,因为我认为它们是造成混乱的根源。让我们使用 good old 匿名 类:
invokeAll(
ids.map(
new Function<String, Callable<Boolean>>()
{
@Override
public Callable<Boolean> apply(String str)
{
return new Callable<Boolean>()
{
@Override
public Boolean call() throws Exception
{
return Boolean.TRUE;
}
};
}
}
)
);
您实际上要问的是 "how I can automatically do this:"
invokeAll(
ids.map(
new Function<String, Callable<Boolean>>()
{
@Override
public Callable<Boolean> apply(String str)
{
return Boolean.TRUE;
}
}
)
);
当然,你不能。 Boolean
不是 Callable<Boolean>
。所以解决方案仅限于您已经确定的内容:
1) 使用 lambda 来创建 Callable
:
() -> Boolean.TRUE
() -> { return Boolean.TRUE; }
2) 创建一个为您执行此操作的方法。例如方法可能比选项 #1 更冗长,所以它不会给你带来任何好处。
抱歉,没有其他方法可以自动改善这一点。
假设我有一个带有这样签名的函数:
public static <T> List<Future<T>> invokeAll(Stream<Callable<T>> tasks) {
... submit given tasks using executor ...
}
我有一个数据流,应该 "wrapped" 成为可调用的并传递给这个函数。像下面这样的简单映射不起作用:
Stream<String> ids = Stream.of("1", "2", "3");
invokeAll(ids.map((id) -> {
// Do a long computation with given ID...
return Boolean.TRUE; // Compilation error: Type mismatch: cannot convert from Boolean to Callable<Object>
}));
一个解决方案是 return lambda 即 returns lambda:
invokeAll(ids.map((id) -> {
return () -> {
// Do a long computation with given ID...
return Boolean.TRUE;
};
}));
另一个(在某种程度上等效)是使用辅助函数:
public static <T> Callable<T> createCallable(T id) {
return () -> {
return id;
};
}
invokeAll(ids.map(ThisClass::createCallable));
但也许有更好/更短的方法来做同样的事情?例如。以某种方式告诉编译器它需要创建一个 return 给定值的 Callable
:
invokeAll(ids.map((Function<String, Callable<Boolean>>) (id) -> {
// Do a long computation with given ID
return Boolean.TRUE;
}));
感谢任何建议。
让我们暂时忽略 lambda,因为我认为它们是造成混乱的根源。让我们使用 good old 匿名 类:
invokeAll(
ids.map(
new Function<String, Callable<Boolean>>()
{
@Override
public Callable<Boolean> apply(String str)
{
return new Callable<Boolean>()
{
@Override
public Boolean call() throws Exception
{
return Boolean.TRUE;
}
};
}
}
)
);
您实际上要问的是 "how I can automatically do this:"
invokeAll(
ids.map(
new Function<String, Callable<Boolean>>()
{
@Override
public Callable<Boolean> apply(String str)
{
return Boolean.TRUE;
}
}
)
);
当然,你不能。 Boolean
不是 Callable<Boolean>
。所以解决方案仅限于您已经确定的内容:
1) 使用 lambda 来创建 Callable
:
() -> Boolean.TRUE
() -> { return Boolean.TRUE; }
2) 创建一个为您执行此操作的方法。例如方法可能比选项 #1 更冗长,所以它不会给你带来任何好处。
抱歉,没有其他方法可以自动改善这一点。