在Java 8中创建方法引用数组的简写方法?

时间:2018-05-18 08:56:05

标签: java lambda java-8 wicket-6

我正在使用Wicket 6 / Java 8并且正在添加一些使用Java 8中的lambda功能的简单类(我知道Wicket的更高版本具有lambda支持但我们现在无法升级)。我正在创建一个有点像PropertyModel的LambdaModel,我希望它不需要硬编码表示该属性的嵌套路径的字符串。

首先,我正在制作一个简单的只读版本。我已经创建了Function接口的Serializable版本来创建以下内容:

public class LambdaModelUtils {
  public static <X,R> IModel<R> ofNested( IModel<X> target, SerializableFunction<?,?>... path ) {
     // creates a model that works through each function in the path in turn
  }
}

我的实现运行良好,但唯一的问题是调用此方法是“有效”的方式会导致编译错误:

IModel<Parent> parentModel = ...
IModel<String> model = LambdaModelUtils.ofNested( parentModel,
                            Parent::getChild, Child::getName );  // Compile time error

我能找到调用该方法的唯一方法是:

SerializableFunction<Parent,Child> path0 = Parent::getChild;
SerializableFunction<Child,String> path1 = Child::getName;
IModel<String> model = LambdaModelUtils.ofNested( parentModel,
                            path0, path1 );  // works

这有点笨拙 - 有更好的方法吗?

我看了here,但这似乎也不起作用:

List<SerializableFunction> path = Arrays.asList( Parent::getChild, Child::getName );

由于

2 个答案:

答案 0 :(得分:3)

如果您使用这些功能来获取嵌套属性,但并未真正使用中间结果,我建议您只使用lambda表达式:

public static <X,R> IModel<R> ofNested(IModel<X> target, SerializableFunction<X, R> path)

IModel<Parent> parentModel = ...
IModel<String> model = LambdaModelUtils.ofNested(parentModel, p -> p.getChild().getName());

由于lambda的目标类型现在已知,而不是通用SerializedFunction<?, ?>,因此SerialiedFunction<X, R> X = ParentR = String位于// Import java utils, for the list to add to the scrollable list import java.util.*; // Import ControlP5 library and declare it import controlP5.*; ControlP5 cp5; // Import the Serial port and declare it import processing.serial.*; Serial myPort; // Create object from Serial class void setup() { size(400, 400); // Initialize the Serial port String portName = Serial.list()[0]; myPort = new Serial(this, portName, 9600);- // Initialize the dropdown list cp5 = new ControlP5(this); List l = Arrays.asList("red", "green", "blue"); /* add a ScrollableList, by default it behaves like a DropdownList */ cp5.addScrollableList("dropdown") .setPosition(100, 100) .setSize(200, 100) .setBarHeight(20) .setItemHeight(20) .addItems(l) ; } void draw() { background(255); } // Dropdown callback function fromthe ScrollableList, triggered when you select an item void dropdown(int n) { /* request the selected item based on index n and store in a char */ String string = cp5.get(ScrollableList.class, "dropdown").getItem(n).get("name").toString(); char c = string.charAt(0); // Write the char to the serial port myPort.write(c); }

答案 1 :(得分:1)

我尝试了类似于你的代码的东西。将方法引用强制转换为函数接口类型可以解决编译错误:

IModel<String> model =
    LambdaModelUtils.ofNested(parentModel,
                             (SerializableFunction<Parent,Child>) Parent::getChild, 
                             (SerializableFunction<Child,String>) Child::getName);

不是最漂亮的解决方案,但至少可以节省您声明path0path1变量的需要。