Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

Stream

tentei implementar o teste para verificar se o usuario ja havia dado 5 lances com as novas alternativas do java 8, depois de algumas tentativas o melhor codigo que cheguei foi este

    public void propoe(Lance lance) {
        if(lances.stream().filter(l -> l.getUsuario().equals(lance.getUsuario())).count() < 5)
            if(lances.isEmpty() || !ultimoLanceDado().getUsuario().equals(lance.getUsuario()))
                lances.add(lance);    
    }

gostaria de saber se esta foi a melhor maneira

1 resposta
solução!

Olá Luiz,

Legal que está praticando e utilizando as funcionalidades do Java 8. A API ganhou algumas melhorias significativas que devem sim ser colocadas em prática.

Mas devemos tomar muito cuidado com uma outra questão muito importante, a semântica do código. Trata-se de quão clara a lógica que o método executa deve ser. A ideia é sempre escrever o código que batendo o olho já sabemos o que faz.

Algumas coisas nesse sentido podem ficar complicadas no código que tira proveito do estilo mais funcional de programação, aninhando chamadas e encadeando condicionais. Deve-se ter parcimônia na utilização destes recursos.

Na minha opinião poderia ter uma abordagem diferente, mas ainda assim tirar proveito das vantagens do Java 8. Poderíamos, por exemplo, simplesmente coletar a stream filtrada com os possiveis lances do usuario proponente, ao invés de encadear os ifs.

Existem algumas práticas legais que visam escrever um Human Readable Code, ou código para seres humanos e não para compiladores. Entre elas uma muitos simples, diz pra evitarmos ter mais de um nivel de indentação dentro de nossos métodos, ajudando a não se perder entre muitos blocos aninhados na hora de interpretar o funcionamento.

Dê uma olhada no possível código abaixo:

public void propoe(Lance lance) {
        List<Lance> lancesDesteUsuario = lances.stream()
                .filter(l -> l.getUsuario().equals(lance.getUsuario()))
                .collect(Collectors.toList());

        if( lancesDesteUsuario.size() >= 5 )
            throw new RuntimeException(); // ou alguma exception mais de negócio

        if( !lances.isEmpty() && ultimoLanceDado().getUsuario().equals(lance.getUsuario()))
            throw new RuntimeException(); // este usuario nao pode dar lance no momento, mesmo lance citado acima sobre a exception

        lances.add(lance);    
    }

Perceba que a simples coleta da stream somada a um nome semântico para a variável já pode ajudar na interpretação da lógica. Assim como uma pitada de programação defensiva, fazendo validações e testando os problemas ao invés de encadear ifs pra checar a condição necessária para efetivar o lance.

Como adicional poderia ainda ter um método auxiliar que isolaria a chamada de ultimoLanceDado().getUsuario().equals(lance.getUsuario()) dentro da condição do if. Reduziria ainda mais os encadeamentos, e somado a um bom nome ajudaria na compreensão da validação. Mas isso deixo a seu critério.

Espero ter ajudado no pensamento. Abraço e bons estudos!