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

Como retornar valor da chamada de um método sobre o resultado de um optional numa única linha de código

Código original:

public BigDecimal getConsumoMedio(TipoMaterial tipoMaterial) {
    if (CollectionUtils.isNotEmpty(estoquesTipoMaterial)) {
        for (EstoqueTipoMaterial estoqueTipoMaterial : estoquesTipoMaterial) {
            if (estoqueTipoMaterial.getTipoMaterial().equals(tipoMaterial)) {
                return estoqueTipoMaterial.getConsumoMedio();
            }
        }
    }

    return NumberUtil.ZERO;
}

Só consegui fazer quebrando em 2 linhas e testando com o isPresent(). Teria como fazer numa única linha?

public BigDecimal getConsumoMedio(TipoMaterial tipoMaterial) {
    if (CollectionUtils.isNotEmpty(estoquesTipoMaterial)) {
        Optional<EstoqueTipoMaterial> optionalEstoqueTipoMaterial = estoquesTipoMaterial.stream()
                .filter(etm -> etm.getTipoMaterial().equals(tipoMaterial)).findFirst();

        return optionalEstoqueTipoMaterial.isPresent() ? optionalEstoqueTipoMaterial.get().getConsumoMedio()
                : NumberUtil.ZERO;
    }

    return NumberUtil.ZERO;
}
1 resposta
solução!

Oi Cássio, tudo bem?

Tem como fazer em uma linha sim, você só precisa chamar duas funçõezinhas, a map() e orElse():

public BigDecimal getConsumoMedio(TipoMaterial tipoMaterial) {
    if (CollectionUtils.isNotEmpty(estoquesTipoMaterial)) {
        return estoquesTipoMaterial.stream()
                .filter(etm -> etm.getTipoMaterial().equals(tipoMaterial))
                .map(EstoqueTipoMaterial::getConsumoMedio)
                .findFirst()
                .orElse(NumberUtil.ZERO);
    }

    return NumberUtil.ZERO;
}

Usando .map(EstoqueTipoMaterial::getConsumoMedio) após o filtro você já chama a função getConsumoMedio para cada EstoqueTipoMaterial encontrado no filter, retornando assim uma stream de BigDecimal já com o consumo médio de cada um deles .

Aí como o map "converteu" nossa Stream pra BigDecimal, o findFirst() vai trazer um resultado do tipo Optional. O orElse(NumberUtil.ZERO) retorna o valor dentro da optional, mas caso ele não exista ele traz o valor passado por parâmetro na função (nesse caso, zero).

Na verdade, se você olhar dentro da implementação do método orElse, você vai ver uma implementação muito semelhante à que você fez na segunda linha:


    /**
     * Return the value if present, otherwise return {@code other}.
     *
     * @param other the value to be returned if there is no value present, may
     * be null
     * @return the value, if present, otherwise {@code other}
     */
    public T orElse(T other) {
        return value != null ? value : other;
    }

Essa é só mais uma das várias funcionalidades que as bibliotecas padrão do java oferecem. Recomendo sempre que você for usar algum objeto novo vale a pena checar a documentação, nem que seja só pra "fuçar" um pouco. Maioria dos métodos tem nome bem intuitivo, se você só der no eclipse um Ctrl + Space e ir fuçando os métodos disponíveis para vários objetos você encontra muitas funçõeszinhas interessantes já prontas que você nem imaginou que existia haha

Enfim, espero ter ajudado. Abraço!