I have a for-statement in java-7 and it's work fine:
Character cha = new Character(',');
String ncourseIds = null;
String pastCourseIds = null;
for (EquivalentCourse equivalentCourse : equivalentCourses) {
if(equivalentCourse.getNcourse() != null){
ncourseIds += equivalentCourse.getNcourse().getId()+ ",";
} else if(equivalentCourse.getPastCourse() != null) {
pastCourseIds +=equivalentCourse.getPastCourse().getId()+",";
}
}
if(!ncourseIds.isEmpty() &&cha.equals(ncourseIds.charAt(ncourseIds.length()-1))) {
ncourseIds = ncourseIds.substring(0, ncourseIds.length()-1);
}
if(!pastCourseIds.isEmpty()&& cha.equals(pastCourseIds.charAt(pastCourseIds.length()-1))) {
pastCourseIds = pastCourseIds.substring(0,pastCourseIds.length()-1);
}
Now I want to convert my code to Stream
& collect
in java-8, I implement half of my business about filter not null Ncourse
:
equivalentCourses.stream().filter(obj -> obj.getNcourse() != null )
.map(obj -> obj.getNcourse().getId()).collect(Collectors.joining(","));
but I don't know to implement it's else-statement
. any help?
Conventional if/else Logic Within forEach() First of all, let's create an Integer List and then use conventional if/else logic within the Integer stream forEach() method: List<Integer> ints = Arrays. asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); ints. stream() .
Java Lambda Expression Syntax 1) Argument-list: It can be empty or non-empty as well. 2) Arrow-token: It is used to link arguments-list and body of expression. 3) Body: It contains expressions and statements for lambda expression.
Lambda Expressions were added in Java 8. A lambda expression is a short block of code which takes in parameters and returns a value. Lambda expressions are similar to methods, but they do not need a name and they can be implemented right in the body of a method.
In java 8, stream api is added with the forEach() method and inside this, we can add the if-else conditions. But, forEach() is called on the streams.
As a stream call chain is complex make two streams - avoiding the conditional branches.
String ncourseIds = equivalentCourses.stream()
.filter(equivalentCourse -> equivalentCourse.getNcourse() != null)
.map(EquivalentCourse::getNcourse)
.map(x -> String.valueOf(x.getId()))
.collect(Collectors.joining(", "));
String pastCourseIds = equivalentCourses.stream()
.filter(equivalentCourse -> equivalentCourse.getNcourse() == null
&& equivalentCourse.getPastCourse() != null)
.map(EquivalentCourse::getPastCourse)
.map(x -> String.valueOf(x.getId()))
.collect(Collectors.joining(", "));
This also is code focusing on the resulting two strings, with an efficient joining.
By the way, if this is for an SQL string, you may use a PreparedStatement with an Array.
Embellishment as commented by @Holger:
String ncourseIds = equivalentCourses.stream()
.map(EquivalentCourse::getNcourse)
.filter(Objects::nonNull)
.map(NCourse::getId)
.map(String::valueOf)
.collect(Collectors.joining(", "));
String pastCourseIds = equivalentCourses.stream()
.filter(equivalentCourse -> equivalentCourse.getNcourse() == null)
.map(EquivalentCourse::getPastCourse)
.filter(Objects::nonNull)
.map(EquivalentCourse::getPastCourse)
.map(PastCourse::getId)
.map(String::valueOf)
.collect(Collectors.joining(", "));
You could group by condition and then remap:
public void booleanGrouping() throws Exception {
List<String> strings = new ArrayList<>();
strings.add("ala");
strings.add("ela");
strings.add("jan");
strings.stream()
.collect(
Collectors.groupingBy(s -> s.endsWith("a")) // using function Obj -> Bool not predicate
).entrySet()
.stream()
.collect(
Collectors.toMap(
e -> e.getKey() ? "Present" : "Past",
e -> e.getValue().stream().collect(Collectors.joining(""))
)
);
}
First stream group by condition, you should use equivalentCourse.getNcourse() != null
second remap collections from value to string. You could introduce:
enum PresentPast{
Present, Past
PresentPast is(boolean v){
return v ? Present : Past
}
}
and change e -> e.getKey() ? "Present" : "Past"
to enum based solution.
Edit:
Solution for else if
:
public Map<Classifier, String> booleanGrouping() throws Exception {
List<String> strings = new ArrayList<>();
strings.add("ala");
strings.add("ela");
strings.add("jan");
// our ifs:
/*
if(!string.endsWith("n")){
}else if(string.startsWith("e")){}
final map should contains two elements
endsWithN -> ["jan"]
startsWithE -> ["ela"]
NOT_MATCH -> ["ala"]
*/
return strings.stream()
.collect(
Collectors.groupingBy(Classifier::apply) // using function Obj -> Bool not predicate
).entrySet()
.stream()
.collect(
Collectors.toMap(
e -> e.getKey(),
e -> e.getValue().stream().collect(Collectors.joining(""))
)
);
}
enum Classifier implements Predicate<String> {
ENDS_WITH_N {
@Override
public boolean test(String s) {
return s.endsWith("n");
}
},
STARTS_WITH_E {
@Override
public boolean test(String s) {
return s.startsWith("e");
}
}, NOT_MATCH {
@Override
public boolean test(String s) {
return false;
}
};
public static Classifier apply(String s) {
return Arrays.stream(Classifier.values())
.filter(c -> c.test(s))
.findFirst().orElse(NOT_MATCH);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With