通过 Java 8 中引入的函数式接口,您可以轻松地将不同的表达式链接到一个新表达式中,如下面的代码片段所示。
public class PredicateChaining {
public static void main(String[] args) {
// verbose, but standard JDK functionality only
Predicate<String> allUpperCase = StringUtils::isAllUpperCase;
Predicate<String> longerThan5 = s -> s.length() > 5;
if (allUpperCase.and(longerThan5).test("PREDICATE")) {
System.out.println("'PREDICATE' is a uppercase text, longer than 5.");
}
// compact, but with utility method ('chain' in this case)
if (chain(StringUtils::isAllLowerCase).and(s -> s.length() < 5).test("test")) {
System.out.println("'test' is a lowercase text, shorter than 5.");
}
}
public static <T> Predicate<T> chain(Predicate<T> test) {
return …Run Code Online (Sandbox Code Playgroud) 我在Java 8中玩.如何返回方法引用?
我能够返回lambda而不是方法引用.
我的尝试:
public Supplier<?> forEachChild(){
return new ArrayList<?>::forEach;
}
Run Code Online (Sandbox Code Playgroud)
要么
public Function<?> forEachChild(){
return new ArrayList<?>::forEach;
}
Run Code Online (Sandbox Code Playgroud) 根据:
https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html
看起来它是可能的,但是尝试真正返回编译错误.由于我们无法使用静态方法实现接口,因此它更有意义.
public class SomeClass {
static public boolean getB(){
return false;
}
}
List<SomeClass> list = new ArrayList<>();
list.add(new SomeClass());
// below causes compile error, which I expect, however documentation indicates oherwise
list.stream().filter(SomeClass::getB).collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
这是编译错误:
"此行的多个标记 - 应该以静态方式访问SomeClass类型的方法getB() - Stream类型中的方法过滤器(Predicate)不适用于参数(SomeClass :: getB)"
构造函数引用(用于函数式编程时是一种特殊类型的方法引用)在没有在Functional接口中声明的抽象方法的任何显式定义的情况下进行求值.你能帮我解决它的解决方法或链接的复杂性吗?特别是对于以下程序如何评估empFactory对象?
public class Employee{
String name;
Integer age;
public Employee(String name, Integer age){
this.name=name;
this.age=age;
}
}
public interface EmployeeFactory{
public abstract Employee getEmployee(String name, Integer age);
}
public class Run{
public static void main(String... args){
EmployeeFactory empFactory=Employee::new;
Employee emp= empFactory.getEmployee("Ammy Sen", 25);
}
}
Run Code Online (Sandbox Code Playgroud) 我想知道是否有一种更优雅的方式来编写以下代码,它利用了一些流,lambdas和方法引用的组合:
final boolean valid = StringUtils.hasText(obj.getFirstName())
&& StringUtils.hasText(obj.getLastName())
&& StringUtils.hasText(obj.getGender())
&& StringUtils.hasText(obj.getDob());
Run Code Online (Sandbox Code Playgroud)
理想情况下,它看起来像这样:
final boolean valid =
something(StringUtil::hasText,
obj.getFirstName(),
obj.getLastName(),
obj.getGender(),
obj.getDob());
Run Code Online (Sandbox Code Playgroud)
也许:
final boolean valid =
something(StringUtil::hasText, obj,
Type::getFirstName(),
Type::getLastName(),
Type::getGender(),
Type::getDob());
Run Code Online (Sandbox Code Playgroud)
显然你可以把所有的getter放到List中,然后使用一个流,但这看起来很罗嗦.在我看来,可能有库函数在JRE中或者在Spring或Apache中执行类似的操作.
编译器如何确保以下语句的等效lambda
BinaryOperator<String> concatOperator = String::concat;
Run Code Online (Sandbox Code Playgroud)
是
BinaryOperator<String> concatOperator = (resultString, inputString) -> resultString.concat(inputString);
Run Code Online (Sandbox Code Playgroud)
并不是
BinaryOperator<String> concatOperator = (resultString, inputString) -> inputString.concat(resultString);
Run Code Online (Sandbox Code Playgroud) 下面的代码给我一个编译错误
.filter(Book::getPrice >200)
Run Code Online (Sandbox Code Playgroud)
编译错误是:此表达式的目标类型应该是功能接口
public void skipData() {
List<Book> bookList = books.stream()
**.filter(Book::getPrice >200)**
.skip(5)
.collect(Collectors.toList());
}
Run Code Online (Sandbox Code Playgroud)
我的Book.java类如下所示:
public final class Book {
private String title;
private String genre;
private double price;
public Book(String title, String genre, double price) {
this.title = title;
this.genre = genre;
this.price = price;
}
public double getPrice() {
return price;
}
//other getters
}
Run Code Online (Sandbox Code Playgroud)
我试图在Eclipse(火星)和cmd线上运行它并看到同样的问题.
但如果我改变.filter(b -> b.getPrice() >200)它的工作原理.
我不清楚为什么方法参考在我的情况下不起作用.
Double::sum是添加双精度的方法参考,即.(a,b) -> a+b.
为什么JDK中没有用于减号的方法参考?是(a,b) -> a-b吗?
我需要有关将lambda表达式更改为方法引用的帮助:
lambda表达式:
intervalCodes.stream().forEach(code -> {
modProfile.addIntervalUsageCode(createIntervalCode(code));
});
Run Code Online (Sandbox Code Playgroud)
我可以将上面的表达式更改为:
intervalCodes.stream().forEach(modProfile::addIntervalUsageCode(createIntervalCode));
Run Code Online (Sandbox Code Playgroud)
有什么建议吗?
我有一个包含错误列表的集合.我想通过密钥(UUID UserId)对它们进行分组.为此,我复制了这个答案的代码:https: //stackoverflow.com/a/30202075/4045364
Collection<FilterError> filterErrors = new ArrayList<FilterError>();
// ... some filterErrors get added to the collection ...
return filterErrors.stream().collect(Collectors.groupingBy(w -> w.getUserId()));
Run Code Online (Sandbox Code Playgroud)
Sonar Lint给了我以下错误:
用方法引用替换此lambda.
->
我尝试过的:
基于这些问题:SONAR:用方法引用和Runable接口替换此lambda:用方法引用替换此lambda.(sonar.java.source未设置.假设为8或更高.)
filterErrors.stream().collect(Collectors.groupingBy(this::getUserId()));
Run Code Online (Sandbox Code Playgroud)
基于这个问题:用方法引用'Objects :: nonNull'替换这个lambda
filterErrors.stream().collect(Collectors.groupingBy(UUID::getUserId()));
Run Code Online (Sandbox Code Playgroud)
两者都给出错误:
此表达式的目标类型必须是功能接口
有没有办法解决这个SonarLint问题?