Replace for loop with lambda

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).

  1. Look at all the tags and find me those named "price"
  2. I'm only interested in the first occurrence (or know that there will be one at most)
  3. Now extract the actual price
  4. Transform the price to the desired format
  5. Or if any of the previous stages fail... return N/A