如果我在OCaml中有一个函数OCaml,我只需键入
let f x = if x=1 then 42 else f x如果这不会隐藏f的旧定义,这正是我想要的。现在,我在Java中寻找一个等价的对象,但是有一个附加的约束,即更新Function f中的引用。我可以创建一个Function-object
Function<Integer, Integer> f = new Function<>() {
@Override
public Integer apply(Integer integer) {
return integer+1;
}
};;现在可以通过以下方式定义新的Function
Function<Integer, Integer> g = new Function<>() {
@Override
public Integer apply(Integer integer) {
if (integer==1)
return 42;
else
return f.apply(integer);
}
};;但是,只有当f声明为final或有效的final时,这才有效。因此,我不能通过f = g;更改引用。我能做什么?
编辑:要清洗,我必须设置f,以便它引用以前引用的旧Function f的Function。所需的代码如下所示:
while(f.apply(i) != 0){
//as above:
g = ... //should use "the newest" f
f = g; //should be used next iteration
//then:
.... //some other code
i = ...;
}发布于 2019-02-20 15:26:35
一个可能的解决方案是使用List:
ArrayList<Function<Integer, Integer>> fList = new ArrayList<>();
fList.add(i -> i+1);
Function<Integer, Integer> g = new Function<>(){
final Function<Integer, Integer> fPre = fList.get(fList.size()-1);
@Override
public Integer apply(Integer integer){
if (integer == 1)
return 42;
else
return fPre.apply(integer);
}
}
fList.add(g);然后,在定义之外需要f = fList.get(fList.size()-1)时使用f。
我们的想法是将所有的f存储在List中,从最老的到最新的。
发布于 2019-02-20 14:24:58
的确,你不能这样做。正如您已经说过的,函数接口中使用的变量必须是最终变量(或者实际上是最终变量)。您可以做的是包装引用,例如使用AtomicReference。然后你就会得到这样的东西:
final AtomicReference<Function<Integer, Integer>> ref = new AtomicReference<>();
Function<Integer, Integer> f = new Function<>() {
@Override
public Integer apply(Integer integer) {
return integer+1;
}
};
ref.set(f);
Function<Integer, Integer> g = new Function<>() {
@Override
public Integer apply(Integer integer) {
if (integer==1)
return 42;
else
return f.apply(integer);
}
};
ref.set(g);该函数将由ref.get()提供。
发布于 2019-02-20 14:41:10
您可以通过嵌套第二个函数来消除本地作用域中的一个变量。除非您需要这两个变量(不太可能,在这种情况下,使用A.Bitner提出的原子引用解决方案是适用的),否则应该可以:
Function<Integer, Integer> f = new Function<Integer, Integer>() {
//this can even be made a local variable of f.apply()
final Function<Integer, Integer> innerFunction = new Function<Integer, Integer>() {
@Override
public Integer apply(Integer integer) {
return integer + 1;
}
};
@Override
public Integer apply(Integer integer) {
if (integer == 1)
return 42;
else
return innerFunction.apply(integer);
}
};和一个等价的lambda表达式:
Function<Integer, Integer> f = i -> {
Function<Integer, Integer> f1 = e -> e + 1;
return i == 1 ? 42 : f1.apply(i);
};https://stackoverflow.com/questions/54788365
复制相似问题