java new构造函数,如何在Java8中初始化通过:: new时将参数传递给类构造函数

I am using java 8 stream API to perform action on a list of Store objects.

Store takes a String argument and a Mapper object. Mapper will be same for all Store object.

Question: How can I pass Mapper object when I initialize Store here .map(Store::new)?

public class Store {

public Store(String name, Mapper mapper) {

}

}

public class Mapper {

}

public class Test {

public static void main(String[] args) {

List names = new ArrayList();

Mapper mapper = new Mapper();

// compile time problem at Store::new because it takes 2 arguments

List actions =

names.stream()

.map(Store::new)

.collect(Collectors.toList());

}

}

解决方案

You can't use a method reference for a constructor that needs to receive a free variable, i.e. a variable from the context.

Please refer to the Java Tutorial, section Method References to find more info about method references.

You can use a lambda expression instead:

Mapper mapper = new Mapper();

List actions =

names.stream()

.map(name -> new Store(name, mapper))

.collect(Collectors.toList());

If, for whatever reason, you insist on using a method reference, you still can, though the solution is more complex and cumbersome. In fact, it's much better from all possible points of view to use a lambda expression instead of the hack I'm introducing below. I'm writing it just to show that method references are good only if you already have a method or constructor whose signature matches the expected one.

Suppose you declare this helper method:

public static Function bindSecond(

BiFunction biFunction,

U free) {

return t -> biFunction.apply(t, free);

}

Here I'm are creating and returning a 1-argument function that applies its only one argument to the given bifunction (a 2-argument function), as well as the given free variable. In other words, I'm binding the given free variable to the given bifunction as its second argument.

In your example, Store::new is actually a bifunction that takes two arguments (name and mapper) and returns a value (the new Store instance), and you are getting that compilation error because Stream.map expects a 1-argument function that takes the element of the stream as its only one parameter.

The bindSecond helper method actually transforms the given bifunction and free variable into a 1-argument function that matches the signature of the Stream.map method.

You could use it as follows:

Mapper mapper = new Mapper();

List actions =

names.stream()

.map(bindSecond(Store::new, mapper))

.collect(Collectors.toList());

But again, I see no point in using this over a simple lambda expression.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值