Reputation: 959
I have an entity Employee
class Employee{
private String name;
private String addr;
private String sal;
}
Now i have list of these employees. I want to filter out those objects which has name = null and set addr = 'A'. I was able to achieve like below :
List<Employee> list2= list.stream()
.filter(l -> l.getName() != null)
.peek(l -> l.setAddr("A"))
.collect(Collectors.toList());
Now list2 will have all those employees whose name is not null and then set addr as A for those employees. What i also want to find is those employees which are filtered( name == null) and save them in DB.One way i achieved is like below :
List<Employee> list2= list.stream()
.filter(l -> filter(l))
.peek(l -> l.setAddr("A"))
.collect(Collectors.toList());
private static boolean filter(Employee l){
boolean j = l.getName() != null;
if(!j)
// save in db
return j;
}
1) Is this the right way?
2) Can we do this directly in lambda expression instead of writing separate method?
Upvotes: 0
Views: 68
Reputation: 298183
Generally, you should not use side effect in behavioral parameters. See the sections “Stateless behaviors” and “Side-effects” of the package documentation. Also, it’s not recommended to use peek
for non-debugging purposes, see “In Java streams is peek really only for debugging?”
There’s not much advantage in trying to squeeze all these different operations into a single Stream pipeline. Consider the clean alternative:
Map<Boolean,List<Employee>> m = list.stream()
.collect(Collectors.partitioningBy(l -> l.getName() != null));
m.get(false).forEach(l -> {
// save in db
});
List<Employee> list2 = m.get(true);
list2.forEach(l -> l.setAddr("A"));
Regarding your second question, a lambda expression allows almost everything, a method does. The differences are on the declaration, i.e. you can’t declare additional type parameters nor annotate the return type. Still, you should avoid writing too much code into a lambda expression, as, of course, you can’t create test cases directly calling that code. But that’s a matter of programming style, not a technical limitation.
Upvotes: 4
Reputation: 6721
If you are okay in using peek for implementing your logic (though it is not recommended unless for learning), you can do the following:
List<Employee> list2= list.stream()
.peek(l -> { // add this peek to do persistence
if(l.getName()==null){
persistInDB(l);
}
}).filter(l -> l.getName() != null)
.peek(l -> l.setAddr("A"))
.collect(Collectors.toList());
You can also do something like this:
List<Employee> list2 = list.stream()
.filter(l->{
boolean condition = l.getName()!=null;
if(condition){
l.setAddr("A");
} else {
persistInDB(l);
}
return condition;
})
.collect(Collectors.toList());
Hope this helps!
Upvotes: 0