C# 闭包和java匿名内部类

C# 闭包和java匿名内部类,c#,java,closures,C#,Java,Closures,有没有人愿意为这样一个闭包(使用C#获得)发布与匿名内部类等价的Java代码 public static Func<int, int> IncrementByN() { int n = 0; // n is local to the method Func<int, int> increment = delegate(int x) { n++; return

有没有人愿意为这样一个闭包(使用C#获得)发布与匿名内部类等价的Java代码

    public static Func<int, int> IncrementByN()
    {
        int n = 0; // n is local to the method

        Func<int, int> increment = delegate(int x)
        {
            n++;
            return x + n;
        };

        return increment;
    }
static void Main(string[] args)
   {

        var v = IncrementByN();
        Console.WriteLine(v(5)); // output 6
        Console.WriteLine(v(6)); // output 8
    }
public static Func IncrementByN()
{
int n=0;//n是该方法的本地
Func increment=委托(int x)
{
n++;
返回x+n;
};
收益增量;
}
静态void Main(字符串[]参数)
{
var v=递增byn();
Console.WriteLine(v(5));//输出6
Console.WriteLine(v(6));//输出8
}
此外,有谁能解释一下,如果词法闭包可用,那么如何获得部分应用程序,反之亦然?对于第二个问题,C#将不胜感激,但这是您的选择。
非常感谢。

我相信这段代码是等效的(至少它产生了所需的输出):


Java中还没有闭包。Lambda表达式将在Java8中出现。然而,您试图翻译的唯一问题是它有状态,我认为lamba表达式不支持这种状态。请记住,它实际上只是一个简写,因此您可以轻松地实现单个方法接口。但是,我相信您仍然可以模拟这一点:

final AtomicInteger n = new AtomicInteger(0);
IncrementByN v = (int x) -> x + n.incrementAndGet();
System.out.println(v.increment(5));
System.out.println(v.increment(6));
虽然我没有测试过这段代码,但它只是作为一个可能在Java8中工作的示例

想想集合api。假设他们有这个接口:

public interface CollectionMapper<S,T> {
    public T map(S source);
}
public interface Func<A, B> {
    B call A();
}
公共接口集合映射器{
公共T图(S来源);
}
以及java.util.Collection上的方法:

public interface Collection<K> {
  public <T> Collection<T> map(CollectionMapper<K,T> mapper);
}
公共接口集合{
公共集合地图(CollectionMapper mapper);
}
现在,让我们看看没有闭包:

Collection<Long> mapped = coll.map(new CollectionMapper<Foo,Long>() {
    public Long map(Foo foo) {
       return foo.getLong();
    }
}
Collection-mapped=coll.map(新的CollectionMapper(){
公共长地图(富富){
返回foo.getLong();
}
}
为什么不写下这个:

Collection<Long> mapped = ...;
for (Foo foo : coll) {
    mapped.add(foo.getLong());
}
集合映射=。。。;
for(Foo-Foo:coll){
mapped.add(foo.getLong());
}
更简洁,对吗

现在介绍lambdas:

Collection<Long> mapped = coll.map( (Foo foo) -> foo.getLong() );
Collection-mapped=coll.map((Foo-Foo)->Foo.getLong();
看看语法有多好?你也可以链接它(我们假设有一个过滤接口,它返回布尔值来决定是否过滤掉一个值):

集合映射和筛选=
coll.map((Foo-Foo)->Foo.getLong()
.filter((长值)->val.longValue()<1000L);

假设我们有一个通用功能接口:

public interface CollectionMapper<S,T> {
    public T map(S source);
}
public interface Func<A, B> {
    B call A();
}
公共接口函数{
B调用A();
}
然后我们可以这样写:

public class IncrementByN {

    public static Func<Integer, Integer> IncrementByN()
    {
        final int n_outer = 0; // n is local to the method

        Func<Integer, Integer> increment = new Func<Integer, Integer>() {
            int n = n_outer; // capture it into a non-final instance variable
                             // we can really just write int n = 0; here
            public Integer call(Integer x) {
                n++;
                return x + n;
            }
        };

        return increment;
    }
    public static void main(String[] args) {
        Func<Integer, Integer> v = IncrementByN();
        System.out.println(v.call(5)); // output 6
        System.out.println(v.call(6)); // output 8
    }
}
公共类递增Byn{
公共静态函数IncrementByN()
{
final int n_outer=0;//n是该方法的本地值
Func increment=新Func(){
int n=n_outer;//将其捕获到非最终实例变量中
//我们可以在这里写int n=0
公共整数调用(整数x){
n++;
返回x+n;
}
};
收益增量;
}
公共静态void main(字符串[]args){
Func v=IncrementByN();
System.out.println(v.call(5));//输出6
System.out.println(v.call(6));//输出8
}
}
一些注意事项:

在您的程序中,您通过引用从封闭范围捕获变量
n
,并可以从闭包中修改该变量。在Java中,您只能捕获
final
变量(因此仅通过值进行捕获)

我在这里做的是从外部捕获
final
变量,然后将其分配到匿名类中的非
final
实例变量中。这允许将“信息”传递到闭包中,同时使其在闭包中可分配。然而,此信息流仅“单向”工作--闭包内对
n
的更改不会反映在封闭范围内。这适用于本例,因为方法中的局部变量在被闭包捕获后不会再次使用


相反,如果您希望能够“双向”传递信息,也就是说,让闭包也能够改变封闭范围内的内容,反之亦然,你需要捕获一个可变的数据结构,如数组,然后对其中的元素进行更改。这更难看,也更不需要这样做。

最好不要给他看,他会嘲笑我们Java人!对于C#中的部分应用,请检查在我的博客文章中,关于这个问题:不用担心,我是一个C++纯粹主义者,所以我也不喜欢C语言!我理解这有点令人费解,这个代码只不过是垃圾。我需要一个例子来说明如何用C代表来获得闭包,所以代码的点是变量n在它的原始之外增加。scope@MarkoTopolnik希望是w当java获得lambdas(明年9月?)时,我们将能够在回答这些问题时表现得更出色一些……它确实也有同样的表现,但我在这里错过了闭包……n是一个匿名类成员,所以(如果我正确获得闭包的话)这不是一个变量绑定到其原始词法环境的情况。我可能错了,我有点困惑,很好地理解了!谢谢!那么闭包和Java匿名内部类之间的关系是什么?如果Java不支持闭包,这种二元性有什么意义?lambda表达式的意义是简化代码。它还允许集合数据结构使用.map()和.foreach()等方法我们习惯于在groovy、python、ruby等语言中使用它,而不会打扰程序员。请看我的编辑。我不理解
n\u outer
的目的。匿名类的成员做的不是吗?例如,assylias的答案很有效。@nawfal:这只是从在一个更现实的例子中,它可能不是