Replace this for with a Lambda solution

Asked

Viewed 90 times

0

I’m studying lambda and wanted to change this solution of for who owns a break.

The solution today suits me, however I wanted to know if the way I am using is ideal or there is a better.

Basically this for takes the items of 1 order and checks if one of the items belongs to type TV. If yes it sends true to the front otherwise false.

I would like to do the same solution but using lambda.

The problem is that in this solution there is a break, and from what I’ve looked at some foruns it’s not possible to break at lambda.

How could I make this solution lambda.

Follows the for down below:

for (final AbstractEntradasPedidosModel abstractEntradasPedidosModel : pedido.getEntradas())
    {

        if (abstractEntradasPedidosModel.getProduto() instanceof TVmodel)
        {
            model.addAttribute("somenteTv", true);
        }
        else
        {
            model.addAttribute("somenteTv", false);
            break;
        }
    }
  • 2

    If the problem is break, Why do you think a lick would solve?

  • @Agaraujo, I removed the [backend] tag because it is irrelevant to the issue. The use of for/break versus lambda/stream (at least the way the question is formulated) is something that is independent of the code being or not in the backend. Inclusive, if you see the description of the tag, it says the following: If the question is not about "back-end", do not use this tag, even if you are using "back-end" in your project

  • @hkotsubo thanks for the information did not know, my question involves the back, but it makes sense what you said.

1 answer

1


The break, by itself, it is not a problem (see a more detailed discussion here and here). Even, in this case seems to be the most appropriate, because the intention of the code seems to be precisely this: if I find a single item whose type is not TV, I can close the loop, because it no longer makes sense to check the rest of the items, so to continue the for? Use the break to stop it and ready.

What can be improved is that you do not need to keep setting the attribute to true every time (every time an item is of the TV type, you are setting the same attribute again). Do this only once, after the for:

boolean somenteTV = true;
for (final AbstractEntradasPedidosModel abstractEntradasPedidosModel : pedido.getEntradas()) {
    if (! (abstractEntradasPedidosModel.getProduto() instanceof TVmodel)) {
        // achei um que não é TV, seta para false e sai do loop
        somenteTV = false;
        break;
    }
}
model.addAttribute("somenteTv", somenteTV);

I mean, you do the for to check all items, but if you find one that is not TV, you do not need to check the rest. Exit loop and at the end seven the attribute with the result of for. If all items are TV type, it does not enter the if, and at the end of loop the value of the attribute will be true.

Remembering that in this case, if the list is empty, the attrition will be true. Already in your code, if the list is empty, it does not enter the for, and atrituto does not even have a set value. If you want to maintain this same behavior, just check the list pedido.getEntradas() (I’m assuming it’s a list) it’s empty:

for ...

if (pedido.getEntradas().size() > 0) {
    model.addAttribute("somenteTv", somenteTV);
}

Or else:

if (pedido.getEntradas().size() > 0) {
    for...
}

That is, if the list is empty, I do not set the value (the behavior is identical to your for original).


But if you want even use lambda, come on...

Although I think that you meant "streams" (which in turn can be used with Amble, and as both were introduced in Java 8, some people actually confuse, or speak one when they meant the other, etc).

Anyway, an alternative is:

boolean somenteTV = pedido.getEntradas().stream()
    .allMatch(entrada -> entrada.getProduto() instanceof TVmodel);

The method allMatch checks that all elements meet the stated condition. In this case, I am checking that all items are of TV type. If you have one that isn’t, the result is false (Obs: the parameter past to allMatch is a lambda).

But even though it looks like you got rid of the for and of break, is just a false impression. Internally the stream need to go through the list items, and according to the documentation, not all the elements will be evaluated if you do not need ("May not evaluate the predicate on all Elements if not necessary for determining the result"). This implies that internally has a break somewhere (or at least some other similar control mechanism).

It is also worth remembering that streams are much less efficient than a loop simple, and for simple cases like this, I don’t know if it’s worth that much.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.