i have a following code:
@Override
public String parsePrice(Document document) {
Elements metaElements = document.getElementsByTag("meta");
for (Element tag : metaElements) {
String content = tag.attr("content");
String item = tag.attr("itemprop");
if ("price".equals(item)) {
return content.equals("0") ? "Free" : content;
}
}
return "Information not available";
}
It will return a price like "7,49$". I want to replace this code with java 8 features. I'm newbie with streams, but tried:
metaElements.stream().filter(tag -> "price".equals(tag.attr("itemprop")))
.findFirst().orElse(null);
But it returns <meta itemprop="price" content="7,49$">
I can't filter like this (missing return statement):
metaElements.stream().filter(tag -> {
String content = tag.attr("content");
String item = tag.attr("itemprop");
if ("price".equals(item)) {
return content.equals("0") ? "Free" : content;
}
}).findFirst().orElse(null);
How to fix it?
Since a for loop is a statement (as is print , in Python 2. x), you cannot include it in a lambda expression. Instead, you need to use the write method on sys. stdout along with the join method.
There are other array utility methods like every , slice , splice , some , concat , sort which everyone should be aware of. Using the right kind of function not only makes the code cleaner, but it also makes it easy to test and extend. Plus you are writing futuristic code by using these functions.
Using a lambda function with a for loop is certainly not the way to approach problems like these. Instead, you can simply use a list comprehension to iterate over the given string/list/collection and print it accordingly, as shown in the solution below.
Your attempt here was close:
metaElements.stream()
.filter(tag -> "price".equals(tag.attr("itemprop")))
.findFirst()
.orElse(null);
you just needed to map
+ orElse
after findFirst
e.g.
return metaElements.stream()
.filter(tag -> "price".equals(tag.attr("itemprop")))
.findFirst()
.map(tag -> tag.attr("content").equals("0") ?
"Free" : tag.attr("content"))
.orElse("Information not available");
You are close!
metaElements.stream()
.filter(tag -> "price".equals(tag.attr("itemprop")))
.findFirst()
.map(tag -> tag.attr("content"))
.map(price -> "0".equals(price) ? "Free" : price)
.orElse("Information not available")
I prefer to keep the lambda's short and chain multiple Stream operators, so the overall code looks more readable (imo).
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