说我有以下代码
public class A {
int x;
public boolean is() {return x%2==0;}
public static boolean is (A a) {return !a.is();}
}
Run Code Online (Sandbox Code Playgroud)
而在另一堂课......
List<A> a = ...
a.stream().filter(b->b.isCool());
a.stream().filter(A::is);
//would be equivalent if the static method is(A a) did not exist
Run Code Online (Sandbox Code Playgroud)
问题是如何使用A :: is类型表示法引用实例方法版本?非常感谢
有人可以向我解释,
为什么传递非静态方法引用方法File::isHidden是可以的,
但是将方法引用传递给非静态方法MyCass::mymethod- 给我一个
"不能对非静态方法进行静态引用"?
public static void main(String[] args) {
File[] files = new File("C:").listFiles(File::isHidden); // OK
test(MyCass::mymethod); // Cannot make a static reference to the non-static method
}
static interface FunctionalInterface{
boolean function(String file);
}
class MyCass{
boolean mymethod(String input){
return true;
}
}
// HELPER
public static void test(FunctionalInterface functionalInterface){}
Run Code Online (Sandbox Code Playgroud) 目的是创建一个可在流过滤器中使用的新谓词:
myCollectionOfElement
.stream()
.filter(
MyStaticHelperClass.compose(MyStaticHelperClass.getSubElement1OfTheElement(),MyStaticHelperClass.getPredicate1OnSubElement1()))
.sorted(MyStaticHelperClass.getOtherSubElement().reversed())
.limit(10)
.collect(Collectors.toList())
Run Code Online (Sandbox Code Playgroud)
getSubElement1OfTheElement()返回Function<E,S>(E包含S属性)
getPredicate1OnSubElement1()返回Predicate<S>
我使用静态函数来公开方法引用和函数.我这样做是因为在Velocity模板中调用了流,并且此上下文不支持lambda语法和方法引用. 我不想为所有可能的组合创建静态函数,所以我真的希望它们是可组合的.
例如,在这里,我不想有静态,getPredicate1OnElementThatCheckProperty1OnTheSubElement1()因为我可以撰写getSubElement1OfTheElement()和getPredicate1OnSubElement1().
所以我需要一个撰写函数:
// returns a new Predicate constructed by applying Predicate predicate on the result of Function function
public static <E,S> Predicate<E> compose(Function<E,S> function, Predicate<S> predicate)
// most intuitive : lambda
return value -> predicate.test(function.apply(value));
// with method references
return function.andThen(predicate::test)::apply;
// predicate.compose is not available because Predicate interface doesn't extends Function …Run Code Online (Sandbox Code Playgroud) 给出了一些Java 8方法函数:
class Foo { Bar getBar() {} }
class Bar { Baz getBaz() {} }
Run Code Online (Sandbox Code Playgroud)
两个访问器的组合看起来像:
Function<Foo, Bar> getBarFromFoo = Foo::getBar;
Function<Bar, Baz> getBazFromBar = Bar::getBaz;
Function<Foo, Baz> getBazFromFoo = getBarFromFoo.andThen(getBazFromBar);
Run Code Online (Sandbox Code Playgroud)
有更简洁的方法吗?这似乎有效
((Function<Foo, Bar>) Foo::getBar).andThen(Bar::getBaz)
Run Code Online (Sandbox Code Playgroud)
但它相当难看.由于优先原因,外围有意义,但为什么演员必要?
(Foo::getBar::getBaz会很好,但唉...)
我有以下类与重载方法:
import java.util.ArrayList;
import java.util.concurrent.Callable;
public abstract class Test {
public void test1 () {
doStuff (ArrayList::new); // compilation error
}
public void test2 () {
doStuff ( () -> new ArrayList<> ());
}
public abstract void doStuff (Runnable runable);
public abstract void doStuff (Callable<ArrayList<String>> callable);
}
Run Code Online (Sandbox Code Playgroud)
该方法test1导致错误消息的编译错误
The method doStuff(Runnable) is ambiguous for the type Test.
我添加了第三种方法test3,如下所示:
public void test3 () {
doStuff ( () -> {
new ArrayList<> ();
});
}
Run Code Online (Sandbox Code Playgroud)
这里doStuff(Runnable) …
我试图通过反向顺序(忽略大小写)对字符串数组进行排序,而不进行修改,只打印它.所以我使用的是Java8流.但我无法做到这一点.
这是我的尝试:
package experimentations.chapter02;
import java.util.Arrays;
import java.util.Comparator;
import java.util.stream.Collectors;
public class StringStream {
public static void main(String[] args) {
sortStrings();
}
public static void sortStrings(){
String[] stringsArray = "The quick brown fox has a dirty ladder".split("\\s+");
System.out.println(
Arrays.stream(stringsArray)
.sorted(Comparator.comparing(String::toLowerCase).reversed())
.collect(Collectors.toList())
);
}
}
Run Code Online (Sandbox Code Playgroud)
这里的问题是String::toLowerCase静态方法不接受Comparator.comparing.
同时,我设法对数组进行排序,但修改它:
public static void sortStrings(){
String[] stringsArray = "The quick brown fox has a dirty ladder".split("\\s+");
System.out.println(
Arrays.stream(stringsArray)
.map(String::toLowerCase)
.sorted(Comparator.reverseOrder())
.collect(Collectors.toList())
);
}
Run Code Online (Sandbox Code Playgroud)
那么,最简单的解决方法是什么?
是否可以将方法引用(例如SomeClass::someMethod)转换为MethodHandle实例?我想要编译时检查的好处(确保存在类和方法)以及使用MethodHandleAPI 内省方法的能力.
用例:当且仅当请求未被特定方法触发时(以避免无限递归),我才需要执行代码.我想要一个编译时检查以确保类/方法存在但运行时检查以将调用者与方法进行比较.
所以回顾一下:是否可以将方法引用转换为MethodHandle?
我试图在我的代码中使用Java 8方法引用.有四种类型的方法参考可用.
随着Static method reference和Constructor reference我有没有问题,但Instance Method (Bound receiver)和Instance Method (UnBound receiver)真搞糊涂了.在Bound接收器中,我们使用Object引用变量来调用方法,如:
objectRef::Instance Method
Run Code Online (Sandbox Code Playgroud)
在UnBound接收器中,我们使用类名来调用方法,如:
ClassName::Instance Method.
Run Code Online (Sandbox Code Playgroud)
我有以下问题:
Bound和Unbound接收方法引用有什么区别?Bound在哪里使用Unbound接收器?我们应该在哪里使我还从Java 8语言特性书中找到了解释Bound和Unbound接收器,但仍然与实际概念混淆.
我可以使用方法参考转换以下代码吗?
List<Text> childrenToRemove = new ArrayList<>();
group.getChildren().stream()
.filter(c -> c instanceof Text)
.forEach(c -> childrenToRemove.add((Text)c));
Run Code Online (Sandbox Code Playgroud)
让我举一个例子来说明我的意思,假设我们有
myList
.stream()
.filter(s -> s.startsWith("c"))
.map(String::toUpperCase)
.sorted()
.forEach(elem -> System.out.println(elem));
Run Code Online (Sandbox Code Playgroud)
使用方法引用它可以写成(最后一行)
myList
.stream()
.filter(s -> s.startsWith("c"))
.map(String::toUpperCase)
.sorted()
.forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)
将表达式转换为方法引用的规则是什么?
这是一个简单的类,说明了我的问题:
package com.example;
import java.util.function.*;
public class App {
public static void main(String[] args) {
App a1 = new App();
BiFunction<App, Long, Long> f1 = App::m1;
BiFunction<App, Long, Void> f2 = App::m2;
f1.apply(a1, 6L);
f2.apply(a1, 6L);
}
private long m1(long x) {
return x;
}
private void m2(long x) {
}
}
Run Code Online (Sandbox Code Playgroud)
f1,指的是App::m1,和被绑定到a1中f1的来电apply,工作完全正常-编译器是幸福的呼叫可以通过f1.apply就好制成.
f2,指App::m2,不起作用.
我希望能够定义一个没有返回类型的未绑定非静态方法的方法引用,但我似乎无法使其工作.
java-8 ×10
method-reference ×10
java ×9
java-stream ×4
lambda ×2
comparator ×1
methodhandle ×1
overloading ×1
void ×1