函数式接口描述如下:
package models;
@FunctionalInterface
public interface EventReducer {
void apply(Event event, GameState state);
}
Run Code Online (Sandbox Code Playgroud)
我在以下类中实现该接口:
package models.reducers;
import models.Event;
import models.EventReducer;
import models.GameState;
import models.events.MinionDeathEvent;
public class MinionDeath implements EventReducer {
@Override
public void apply(Event event, GameState state) {
MinionDeathEvent deathEvent = (MinionDeathEvent)event;
deathEvent.getPlayer().getBoard().remove(deathEvent.getMinion());
}
}
Run Code Online (Sandbox Code Playgroud)
如何将实现作为参数传递?例如,
private static final Map<EventType, EventReducer> ReducersMap = Map.ofEntries(
entry(EventType.DEATH, MinionDeath::apply);
);
Run Code Online (Sandbox Code Playgroud)
显然,MinionDeath::apply这不是一条路
我一直在尝试用一而在Java函数式编程,并发现我开始喜欢使用的@FunctionalInterface从功能java.util.function包,如功能,BiFunctions,UnaryOperators,谓语,BiPredicates等代替简单的私有方法我类。我知道他们的应用程序更推荐作为参数传递给另一个函数,这就是我通常倾向于使用它们的方式,但我现在只是发现它们立即并且以某种方式更好。
事实上,我现在倾向于将其中一些声明为变量,然后在需要时在我的类中使用。
我似乎没有找到任何使用这些而不是简单方法的指南或缺点。
那么:以这种方式使用它们有什么缺点吗?
为什么更喜欢:
private boolean foo(final int a, final int b){
return a < b;
}
Run Code Online (Sandbox Code Playgroud)
代替:
private final BiPredicate<Integer,Integer> foo = (a,b) -> a < b;
Run Code Online (Sandbox Code Playgroud)
我在最近的项目中如何使用它们的一个例子:
private final BiFunction<BoardPosition, Pair<Integer, Integer>, BoardPosition> sumBoardPosWithPair = (pos,
pair) -> new BoardPositionImpl(pos.getX() + pair.getX(), pos.getY() + pair.getY());
private final Function<Pair<Integer, Integer>, UnaryOperator<BoardPosition>> unaryCreator = (
axis) -> (p) -> this.sumBoardPosWithPair.apply(p, axis);
/**
* If you need to call the fromFunction method twice for specular …Run Code Online (Sandbox Code Playgroud) 在我的代码中,我们必须将欧元转换为欧分:将 aBigDecimal作为输入,我们必须将其乘以 100。
我们需要多次应用这种转换,所以我们决定使用UnaryOperatorfrom java.util.function:
private static final UnaryOperator<BigDecimal> CONVERT_EURO_TO_CENTS =
input -> input.multiply(BigDecimal.valueOf(100)).setScale(0, RoundingMode.DOWN);
Run Code Online (Sandbox Code Playgroud)
然后我们使用CONVERT_EURO_TO_CENTS如下:
[.....]
CONVERT_EURO_TO_CENT.apply(<aBigDecimal>)
[.....]
Run Code Online (Sandbox Code Playgroud)
将 声明UnaryOperator为常量 ( static final)可能是危险的,以避免多线程环境中的数据不一致(线程安全)?
我是使用流和函数式接口进行编程的新手,并且在文档中java.util.function.BiConsumer描述了如下方法accept,但尚不清楚
void accept(T t,
U u)
Performs this operation on the given arguments.
Parameters:
t - the first input argument
u - the second input argument
Run Code Online (Sandbox Code Playgroud)
函数接口可以使用 lamda 表达式来引用,如下所示
BiConsumer<String,String> a=(a,b)->{
}
Run Code Online (Sandbox Code Playgroud)
但“此操作在这里到底意味着什么”。提前致谢
有一些接近Callable<Boolean>,它返回boolean不Boolean,和投掷也不例外?
我想用它 DoIt.until( ()-> someQueryWithBooleanResult() );
是的,我知道,Predicate<Void>有点相似,但我不想使用虚拟参数.
Comparable 和 Comparator 是功能接口,Comparator 也被声明为 @FunctionalInterface 但为什么 Comparable 在 jdk 1.8 中没有声明为 @FunctionalInterface 虽然它是其中之一?
通过JOOL库JOOQ,Streams上提供了许多功能接口和实用程序类.
我的问题是这个库支持1-16个参数功能接口.这有道理吗?因为我一直在练习中将方法中的参数数量减少到3.虽然可接受的数量根据不同的思想领袖而变化.但没有人说16.
请参阅StackOverflow本身的参考链接:
此外,它提供了一个实用程序类Seq,它看起来仅限于顺序处理.
使用JOOL具有良好过去经验的人可以回答为什么我应该使用JOOL看起来像它包含的很多东西是没用的吗?
我知道方法签名包括方法名称及其参数列表。
但是throws Exception呢?
public List<ServiceStatusVo> listServiceStatuses() throws RetrieverException {
...
return list;
}
Run Code Online (Sandbox Code Playgroud)
如果不包括在内,那么为什么我不能传入以下 lambda:
() -> listServiceStatuses()
Run Code Online (Sandbox Code Playgroud)
但我可以通过
() -> {
try {
return listServiceStatuses();
} catch (RetrieverException e) {
}
}
Run Code Online (Sandbox Code Playgroud)
我也可以再次扔掉它
() -> {
try {
return listServiceStatuses();
} catch (RetrieverException e) {
throw e;
}
}
Run Code Online (Sandbox Code Playgroud)
我知道Supplier<T>函数式接口,如果 throws不是方法签名的一部分,那真的让我感到困惑。
谢谢您的帮助。
在最近的一次采访中,有人问我一个问题:“我们怎么能说java8中的功能接口类似于标记接口”。
我无法回答这个问题。
但是我认为标记甚至没有任何方法,而功能接口必须要覆盖一种方法。
有人可以帮助我理解这是否在某些情况下是有效的论点,或者问题本身是错误的?
java interface marker-interfaces java-8 functional-interface
有没有一种功能性的方法来首先收集流的元素,然后立即将集合传递给消费者?换句话说,一种在将所有流元素作为集合而不是一个接一个地应用终端操作之前等待流结束的构造?
例如,您是否可以将以下内容实现为单行:
Stream<Event> stream = // a stream of events
List<Event> list = stream.collect(Collectors.toList());
doProcessEvents(list);
Run Code Online (Sandbox Code Playgroud)
作为一种解决方法,我可以 (ab) 使用Collectors.collectingAndThen()和 aFunction来实现我正在寻找的结果:
Function<List<Event>, Void> processingFunction = (list -> {
doProcessEvents(list);
return null;
});
Stream<Event> stream = // a stream of events
stream.collect(Collectors.collectingAndThen(Collectors.toList(), processingFunction);
Run Code Online (Sandbox Code Playgroud)
我考虑过的其他替代方案(但不起作用)是如果该collectingAndThen()方法有一个Consumer作为第二个参数,例如,Collectors.collectingAndThen(Collector downstream, Consumer consumer)或者如果Consumer接口有一个finish()在流中的最后一个元素被消耗后执行的方法:
class EventConsumer implements Consumer<Event> {
private final List<Event> list = new LinkedList<>();
@Override
public void accept(Event ev) {
events.add(ev);
}
public void …Run Code Online (Sandbox Code Playgroud)