Implementation using API-Streams and API-Lambda Java 8

Asked

Viewed 474 times

0

Good Staff.

Trying unsuccessfully to solve a proposed exercise using the new features of the java 8 Lambda and Streams Apis. In this exercise you can only create and change methods signature in the Cartshopping class. The idea is to use the features of the Streams and Lambda Apis in resolution. Any idea how I can attack the resolution?

Carrinhocomprasfactory

public CarrinhoCompras criar(String identificacaoCliente) {
} 

public BigDecimal getValorTicketMedio() {
}

public boolean invalidar(String identificacaoCliente) {
}

Pushcart

public void adicionarItem(Produto produto, BigDecimal valorUnitario, int quantidade) {
}

public boolean removerItem(Produto produto) {
}

public boolean removerItem(int posicaoItem) {
}

public BigDecimal getValorTotal() {
}

Product

public class Produto {

    private Long codigo;
    private String descricao;

    public Produto(Long codigo, String descricao) {
    }

    //getters and setters
}

Item

public class Item {

    private Produto produto;
    private BigDecimal valorUnitario;
    private int quantidade;

    public Item(Produto produto, BigDecimal valorUnitario, int quantidade) {
    }

    public BigDecimal getValorTotal() {
    }

    //getters and setters
}
  • 1

    What problem are you trying to solve?

  • implement the body of methods without changing the signature using the Stream and Lambda Apis

  • 1

    It’s not very clear what you’re trying to do.

  • The idea is to implement the body of methods without changing their signature. You can only change the Cartshop class. Nor did I understand how to solve, it was an admissional exercise for a company. That’s why I wanted to hear opinions.

  • I think information is missing in this exercise rsrs I don’t see how to apply Stream and Lambda in this exercise.

1 answer

1


A possible solution to follow. It has no ideal architecture and performance, but illustrates several elements of Java 8, within the constraints of the question.

Product class:

package br.teste.compras;

public class Produto {

  private Long codigo;
  private String descricao;

  public Produto(Long codigo, String descricao) {
    setCodigo(codigo);
    setDescricao(descricao);
  }

  // getters and setters omitidos

}

Item class:

package br.teste.compras;

import java.math.BigDecimal;

public class Item {
  private Produto produto;
  private BigDecimal valorUnitario;
  private int quantidade;

  public Item(Produto produto, BigDecimal valorUnitario, int quantidade) {
    setProduto(produto);
    setValorUnitario(valorUnitario);
    setQuantidade(quantidade);
  }

  public BigDecimal getValorTotal() {
    Multiplicador<Integer> multiplicador = (val1, val2) -> val2.multiply(BigDecimal.valueOf(val1));
    return multiplicador.multiplicar(getQuantidade(), getValorUnitario());
  }

  @FunctionalInterface
  interface Multiplicador<F> {
    BigDecimal multiplicar(F val1, BigDecimal val2);
  }

  //getters and setters omitidos

}

Classe Carrinhocompras:

package br.teste.compras;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

public class CarrinhoCompras {
  private List<Item> items = new ArrayList<Item>();

  //São admitidas repetições de um mesmo produto.
  //Para uma melhor arquitetura, o valorUnitario deveria ser atributo de Produto.
  public void adicionarItem(Produto produto, BigDecimal valorUnitario, int quantidade) {
    items.add(new Item(produto, valorUnitario, quantidade));
  }

  public boolean removerItem(Produto produto) {
    return items.remove(produto); //retorna true se removido
  }

  public boolean removerItem(int posicaoItem) {
    //Não é a implementação mais eficiente, mas ilustra o uso do Java 8. 
    return items.removeIf(item -> posicaoItem == items.indexOf(item));
  }

  public BigDecimal getValorTotal() {
    return items.stream().map(Item::getValorTotal).reduce(BigDecimal.ZERO, BigDecimal::add);
  }

  //Único método adicionado à classe, conforme permitido pelo enunciado.
  public List<Item> getItems() {
    return items;
  }

}

Class Carrinhocomprasfactory:

package br.teste.compras;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.Map;

public class CarrinhoComprasFactory {
  //Armazena os clientes e seus carrinhos.
  private final Map<String, CarrinhoCompras> map = new HashMap<>();

  public CarrinhoCompras criar(String identificacaoCliente) {
    map.put(identificacaoCliente, new CarrinhoCompras());
    return map.get(identificacaoCliente);
  }

  //Não está clara a função deste método, mas aqui retorna o valor médio dos valores totais nos carrinhos dos clientes.
  public BigDecimal getValorTicketMedio() {
    return map.values().stream()
              .map(carrinho -> carrinho.getValorTotal())
              .reduce(BigDecimal.ZERO, BigDecimal::add)
              .divide(BigDecimal.valueOf(map.size()), RoundingMode.FLOOR);
  }

  //Retorna true se existe esse cliente.
  public boolean invalidar(String identificacaoCliente) {
    return map.remove(identificacaoCliente) != null;
  }

}

A test class, also with some elements of Java 8:

package br.teste.compras;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;
import java.util.stream.LongStream;

public class Build {

    public static void main(String[] args) {
        CarrinhoComprasFactory factory = new CarrinhoComprasFactory();
        Map<Long, CarrinhoCompras> map = new HashMap<>();
        //Inclui 3 clientes
        LongStream.range(1, 4).forEach(idx -> map.put(idx, factory.criar("Cliente " + idx)));
        //adiciona 3 produtos no carrinho de cada cliente.
        map.forEach((clienteID, carrinho) -> {
            System.out.println("*** Cliente " + clienteID + " ***");
            LongStream.range(1, 4).forEach(idx -> {
                Long random = ThreadLocalRandom.current().nextLong(1, 100);
                carrinho.adicionarItem(
                        new Produto(random * 100, "Produto " +  clienteID * 1000 + idx),
                        BigDecimal.valueOf(random), (int)(random % 11 + 1));
            });
            //imprime os items gerados
            System.out.println(carrinho.getItems().stream()
                    .map(item -> item.getProduto().getDescricao() + "(" + item.getProduto().getCodigo() + "): " +
                            item.getQuantidade() + " x $" + item.getValorUnitario() + " = $" + item.getValorTotal())
                    .collect(Collectors.joining(", ")));
        });
        System.out.println("Media clientes 1, 2 e 3: $" + factory.getValorTicketMedio());
        factory.invalidar("Cliente 3");
        map.remove(Long.valueOf(3)); // :-(
        map.get(Long.valueOf(2)).removerItem(1);
        map.get(Long.valueOf(1)).removerItem(map.get(Long.valueOf(1)).getItems().get(0).getProduto());
        System.out.println("Media clientes 1 e 2: $" + factory.getValorTicketMedio());
    }

}

Since the construction of item values is random, below is an example of output printed by the above class (Build):

*** Cliente 1 ***
Produto 10001(4400): 1 x $44 = $44, Produto 10002(2700): 6 x $27 = $162, Produto 10003(6900): 4 x $69 = $276
*** Cliente 2 ***
Produto 20001(3500): 3 x $35 = $105, Produto 20002(5200): 9 x $52 = $468, Produto 20003(9500): 8 x $95 = $760
*** Cliente 3 ***
Produto 30001(6700): 2 x $67 = $134, Produto 30002(2800): 7 x $28 = $196, Produto 30003(5000): 7 x $50 = $350
Media clientes 1, 2 e 3: $831
Media clientes 1 e 2: $673
  • 1

    Great answer. Thank you. I will mark as ideal answer.

Browser other questions tagged

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