-->

Method reference in java

2019-06-03 09:51发布

问题:

I'm exploring method reference in java, and just curious if following can be converted to a method reference

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);
list.forEach(item -> new SomeClass(item).someMethod(item));

I tried the following, but that didn't work

list.forEach(SomeClass::new::someMethod);

回答1:

There are four types of method reference, that you can use based on java specification , you can use only this type method reference

  1. Reference to a static method Class::staticMethodName
  2. Reference to a constructor ClassName::new
  3. Reference to an instance method of an arbitrary object of a particular type lass::instanceMethodName

  4. Reference to an instance method of a particular object object::instanceMethodName



回答2:

There is no way to resolve the issue in the way you provided. But it could be done by defining the someMethod method as static:

list.forEach(item -> SomeClass.someMethod(item));
list.forEach(SomeClass::someMethod);

The statement SomeClass::new::someMethod is incorrect. Strictly speaking, SomeClass::new refers to a piece of constructor code (like a Consumer), it does not return a new instance while you need an object to make a method reference SomeClassinstance::someMethod.

EDIT:
I really don't see any advantages of the approach:

map(SomeClass::new).forEach(SomeClass::someMet‌hod)

because it leads to creation a portion of useless SomeClass instances with items that also will not be used.



回答3:

Would this be an option may be?

Function<Integer, SomeClass> f = SomeClass::new;
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);
list.forEach(i -> f.apply(i).someMethod());

And obviously a method to do what you want is another way to go:

private static void method(int item) {
    new SomeClass(item).someMethod();
}

list.forEach(YourClass::method);


回答4:

I have thought of following code. Although, it is not using method reference but should be more readable than imperative style coding.

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);
Function<Integer, SomeClass> someClass = SomeClass::new;
BiConsumer<SomeClass, Integer> someMethod = SomeClass::someMethod;
list.forEach(item -> someMethod.accept(someClass.apply(item), item));