使用Lambda表达式创建和填充对象作为参数。

huangapple go评论78阅读模式
英文:

Using Lambdas to create and populate objects as an argument

问题

以下是已翻译的内容:

我发现Java的Lambda语法与其他语言中更直接的Lambda表达式相比,独特地晦涩和令人困惑。

我理解的是,您可以将Lambda作为方法参数代替对象进行传递,语法大致如下:

method(() -> { /*返回值的代码*/ } )

但我无法得到能够正常工作的语法。

我想要构建一个对象列表,并且我希望为每个新对象填充唯一的数据(比如说一个Math.random()的值)。所以我尝试着这样做:

ArrayList<MyType> mytypes = new ArrayList<>();
mytypes.add( () -> { MyType m = new MyType(); m.populate(Math.random()); return m; } );

但显然那不合法,尽管它似乎与网上存在的最简单的例子相匹配。我还尝试过:

mytypes.add( t -> { MyType m = new MyType(); m.populate(Math.random()); return m; } );

mytypes.add( MyType t -> { MyType m = new MyType(); m.populate(Math.random()); return m; } );

mytypes.add( (MyType t) -> { MyType m = new MyType(); m.populate(Math.random()); return m; } );

mytypes.add( { MyType m = new MyType(); m.populate(Math.random()); return m; } );

这些都是基于我在网上看到的各种语法尝试的,但都没有提供足够的信息。

那么,这其中有什么问题吗?如何做到这一点?这真的不可能吗?(真可惜,因为大多数其他使用Lambda的语言似乎都可以直观地实现这一点。)

英文:

I find Java lambda syntax to be uniquely obscure and confusing, compared to other languages' more straightforward lambdas...

My understanding is that you can pass a lambda in lieu of an object as a parameter of a method, and the syntax goes something like

method(() -&gt; { /*code to return value*/ } )

But I can't get a syntax that will work.

I want to build a list of objects, and I want to populate each new object with unique data (let's say a Math.random() value). So I'm trying to do this:

ArrayList&lt;MyType&gt; mytypes = new ArrayList&lt;&gt;();
mytypes.add( () -&gt; { MyType m = new MyType(); m.populate(Math.random()); return m } );

But that apparently isn't legit, although it seems to match what minimal examples there are out there for doing this. I've also tried

mytypes.add( t -&gt; { MyType m = new MyType(); m.populate(Math.random()); return m } );

mytypes.add( MyType t -&gt; { MyType m = new MyType(); m.populate(Math.random()); return m } );

mytypes.add( (MyType t) -&gt; { MyType m = new MyType(); m.populate(Math.random()); return m } );

mytypes.add( { MyType m = new MyType(); m.populate(Math.random()); return m } );

based on various syntaxes seen online, which have been barely informative.

So what is wrong with any of this? How to do this? Is it just not possible? (Shame, because most other languages using lambdas would seem to do it intuitively.)

答案1

得分: 2

Lambdas 只能在需要函数式接口实例的地方使用。函数式接口是一个只有一个抽象方法的接口。Lambda 表达式会被编译成实现该接口的实例,并且 Lambda 的主体部分将成为该单个接口方法的实现。

在这里:

ArrayList<MyType> mytypes = new ArrayList<>();
mytypes.add(() -> { MyType m = new MyType(); m.populate(Math.random()); return m; });

add 没有接受函数式接口作为参数的重载。因此上述代码无法编译通过。应该将其改写为单独的语句:

ArrayList<MyType> mytypes = new ArrayList<>();
MyType m = new MyType();
m.populate(Math.random());
mytypes.add(m);

为了完整起见,你可以使用一个小技巧,实际上将 Lambda 强制转换为 Supplier<MyType>,这是一个函数式接口,然后调用 get 来运行 Lambda 中的代码。

mytypes.add(((Supplier<MyType>)(() -> { MyType m = new MyType(); m.populate(Math.random()); return m; })).get());

但请不要这样写代码... 我不知道在哪些“其他语言”中这样做是可以的,但这不是我们在 Java 中的做法。

英文:

Lambdas can only be used where an instance of a functional interface is expected. A functional interface is an interface with a single abstract method. The lambda gets compiled into an instance implementing that interface, and the lambda body becomes the implementation of that single interface method.

Here:

ArrayList&lt;MyType&gt; mytypes = new ArrayList&lt;&gt;();
mytypes.add( () -&gt; { MyType m = new MyType(); m.populate(Math.random()); return m } );

No overload of add takes a functional interface as a parameter. Hence the above does not compile. It should instead be written as separate statements:

ArrayList&lt;MyType&gt; mytypes = new ArrayList&lt;&gt;();
MyType m = new MyType();
m.populate(Math.random());
mytypes.add(m);

For completeness' sake, you can technically write it using a lambda with a trick, by casting the lambda to a Supplier&lt;MyType&gt;, which is a functional interface, and then call get to actually run the code in the lambda.

mytypes.add( ((Supplier&lt;MyType&gt;)(() -&gt; { MyType m = new MyType(); m.populate(Math.random()); return m })).get() );

But please don't write code like this... I don't know what "other languages" in which this is acceptable, but this is not how we do it in Java.

huangapple
  • 本文由 发表于 2020年8月27日 11:39:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/63608796.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定