Reputation: 47
I am new in functional programming. I want to understand which concept am I missing here.
Stream<Employee> stream1 = getEmployeeListOne().stream();
Stream<Employee> stream2 = getEmployeeListTwo().stream();
Predicate<Employee>predicate=x->x.getFirstName().startsWith("L");
//Below line is compile time error
List<Employee>list=stream1.filter((x->x.getFirstName().startsWith("L")).or(x->x.getLastName().startsWith("L"))).collect(Collectors.toList());
//Below line works well
//List<Employee>list2=stream1.filter(predicate.or(x->x.getLastName().startsWith("L"))).collect(Collectors.toList());
It simply says lambda expression not expected here
Upvotes: 1
Views: 134
Reputation: 424993
A Predicate
has the or()
method.
A lambda does not.
If you assign the lambda to a variable of type Predicate
, you’re fulfilling the implementation of Predicate
’s single unimplemented method test()
, which only then has an or()
method.
Upvotes: 1
Reputation: 6963
THis is how i have tried to do it, extract similar test condition in a method , make predicate return boolean of composite condition.
The chaining does work if you write
final Predicate<Employee> onlyEmpNameStarsWithL = employee -> nameStartsWithL(employee.firstName);// || nameStartsWithL(employee.lastName);
and then use full code as below:
List<Employee> allEmployeeWithLInName = employeeStream.filter(Objects::nonNull)
.filter(onlyEmpNameStarsWithL.or(e -> nameStartsWithL(e.lastName)))
.collect(Collectors.toList());
allEmployeeWithLInName.forEach(System.out::println);
Or the complete other approach
final Predicate<Employee> onlyEmpNameStarsWithL =
employee -> nameStartsWithL(employee.firstName) || nameStartsWithL(employee.lastName);
helper method
static boolean nameStartsWithL(String name) {
return name != null && name.startsWith("L");
}
Full source code
package examples;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
class Employee {
String firstName;
String lastName;
public Employee(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
@Override
public String toString() {
return "Employee{" +
"firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
'}';
}
}
public class LambdaPredicate {
static boolean nameStartsWithL(String name) {
return name != null && name.startsWith("L");
}
public static void main(String[] args) {
List<Employee> employeeList = Arrays.asList(
new Employee("A", "P"),
new Employee("B", "L"),
null,
new Employee("C", "Q"),
new Employee("L", "I"),
new Employee("L", "L")
);
final Predicate<Employee> onlyEmpNameStarsWithL = employee -> nameStartsWithL(employee.firstName) || nameStartsWithL(employee.lastName);
Stream<Employee> employeeStream = employeeList.stream();
List<Employee> allEmployeeWithLInName = employeeStream.filter(Objects::nonNull)
.filter(onlyEmpNameStarsWithL)
.collect(Collectors.toList());
allEmployeeWithLInName.forEach(System.out::println);
}
}
Output
Employee{firstName='B', lastName='L'}
Employee{firstName='L', lastName='I'}
Employee{firstName='L', lastName='L'}
Upvotes: 0