/TesteTreeMap/src/lei/li3/g50/modulos/compras/Compras.java

https://gitlab.com/andrerfcsantos/GesthiperJava · Java · 433 lines · 323 code · 88 blank · 22 comment · 49 complexity · 5586cb47a86661307e98500f5fccc33a MD5 · raw file

  1. package lei.li3.g50.modulos.compras;
  2. import java.io.Serializable;
  3. import java.util.ArrayList;
  4. import java.util.Arrays;
  5. import java.util.TreeMap;
  6. import java.util.List;
  7. import java.util.Map;
  8. import java.util.Objects;
  9. import java.util.TreeMap;
  10. import java.util.TreeSet;
  11. import lei.li3.g50.excepcoes.ClienteNaoComprouProdutoException;
  12. import lei.li3.g50.excepcoes.ClienteNaoExisteException;
  13. import lei.li3.g50.excepcoes.ProdutoNaoExisteException;
  14. import lei.li3.g50.modulos.dados.Cliente;
  15. import lei.li3.g50.modulos.dados.Compra;
  16. import lei.li3.g50.modulos.dados.Mes;
  17. import lei.li3.g50.modulos.dados.Produto;
  18. import lei.li3.g50.modulos.dados.TipoCompra;
  19. import lei.li3.g50.utilitarios.ComparatorParClienteProdutosDiferentes;
  20. import lei.li3.g50.utilitarios.ComparatorTriploClienteQtdCompradaDinheiro;
  21. import lei.li3.g50.utilitarios.Matriz_Double_12x2;
  22. import lei.li3.g50.utilitarios.Matriz_Int_12x2;
  23. import lei.li3.g50.utilitarios.ParClienteProdutosDiferentes;
  24. import lei.li3.g50.utilitarios.ParProdutoQuantidadeComprada;
  25. import lei.li3.g50.utilitarios.TriploClienteQtdCompradaDinheiro;
  26. public class Compras implements Serializable {
  27. /**
  28. *
  29. */
  30. private static final long serialVersionUID = 7175792608614138915L;
  31. private int numeroComprasValorZero;
  32. private int numeroClientesDistintosPorMes[];
  33. private int numeroTotalClientesDistintos;
  34. private TreeMap<Cliente, FichaClienteCompras> arvoreClientes;
  35. private TreeMap<Produto, ParProdutoNClientes> arvoreParesProdutoNClientes;
  36. /*
  37. CONSTRUCTORES
  38. */
  39. public Compras() {
  40. this.numeroComprasValorZero = 0;
  41. numeroTotalClientesDistintos = 0;
  42. numeroClientesDistintosPorMes = new int[12];
  43. arvoreClientes = new TreeMap<>();
  44. arvoreParesProdutoNClientes = new TreeMap<>();
  45. }
  46. public Compras(Compras compras) {
  47. numeroTotalClientesDistintos = compras.getTotalClientesDistintos();
  48. this.numeroComprasValorZero = compras.getNumeroComprasValorZero();
  49. for (int i = 0; i < 12; i++) {
  50. this.numeroClientesDistintosPorMes[i] = compras.numeroClientesDistintosPorMes[i];
  51. }
  52. for (Map.Entry<Cliente, FichaClienteCompras> entrada : compras.arvoreClientes.entrySet()) {
  53. this.arvoreClientes.put(entrada.getKey().clone(), entrada.getValue().clone());
  54. }
  55. for (Map.Entry<Produto, ParProdutoNClientes> entrada : compras.arvoreParesProdutoNClientes.entrySet()) {
  56. this.arvoreParesProdutoNClientes.put(entrada.getKey().clone(), entrada.getValue().clone());
  57. }
  58. }
  59. /*
  60. REGISTOS
  61. */
  62. public void registaCliente(Cliente cliente) {
  63. this.arvoreClientes.put(cliente.clone(), new FichaClienteCompras());
  64. }
  65. public void registaProduto(Produto produto) {
  66. this.arvoreParesProdutoNClientes.put(produto.clone(), new ParProdutoNClientes());
  67. }
  68. public void registaCompra(Compra compra) {
  69. Mes mes = compra.getMes();
  70. Produto produto = compra.getProduto();
  71. FichaClienteCompras ficha_cliente;
  72. try {
  73. ficha_cliente = getFichaClienteNoClone(compra.getCliente());
  74. } catch (ClienteNaoExisteException ex) {
  75. ficha_cliente = new FichaClienteCompras();
  76. this.arvoreClientes.put(compra.getCliente().clone(), ficha_cliente);
  77. }
  78. if (ficha_cliente.getNumComprasMes(mes, TipoCompra.AMBOS) == 0) {
  79. numeroClientesDistintosPorMes[mes.getIndiceArray()]++;
  80. }
  81. if (ficha_cliente.getTotalCompras() == 0) {
  82. numeroTotalClientesDistintos++;
  83. }
  84. ParProdutoNClientes par_prod_nclis;
  85. try {
  86. par_prod_nclis = this.getParProdutoNClientesNoClone(produto);
  87. } catch (ProdutoNaoExisteException ex) {
  88. par_prod_nclis = new ParProdutoNClientes();
  89. this.arvoreParesProdutoNClientes.put(compra.getProduto().clone(), par_prod_nclis);
  90. }
  91. try {
  92. Matriz_Int_12x2 comprasMeses = ficha_cliente.getNumComprasProdutoMeses(produto);
  93. if (comprasMeses.getValorMesTipoCompra(mes, TipoCompra.AMBOS) == 0) {
  94. par_prod_nclis.addNumeroClientesMes(mes, 1);
  95. }
  96. if (comprasMeses.getSomaTotal() == 0) {
  97. par_prod_nclis.addNumeroTotalClientesDistintos(1);
  98. }
  99. } catch (ClienteNaoComprouProdutoException ex) {
  100. par_prod_nclis.addNumeroClientesMes(mes, 1);
  101. par_prod_nclis.addNumeroTotalClientesDistintos(1);
  102. }
  103. if (compra.getPreco() == 0) {
  104. this.numeroComprasValorZero++;
  105. }
  106. ficha_cliente.regista_compra(compra);
  107. }
  108. /*
  109. GETTERS ESPECIFICOS CLASSE
  110. */
  111. /*COMPRAS*/
  112. public int getNumeroComprasValorZero() {
  113. return numeroComprasValorZero;
  114. }
  115. /*CLIENTES DISTINTOS*/
  116. public int getTotalClientesDistintos() {
  117. return this.numeroTotalClientesDistintos;
  118. }
  119. public int getNumeroClientesDistintosMes(Mes mes) {
  120. return this.numeroClientesDistintosPorMes[mes.getIndiceArray()];
  121. }
  122. public int[] getNumeroClientesDistintosMesesAsArray() {
  123. int resultado[] = new int[12];
  124. for (int i = 0; i < 12; i++) {
  125. resultado[i] = this.numeroClientesDistintosPorMes[i];
  126. }
  127. return resultado;
  128. }
  129. public Map<Mes, Integer> getNumeroClientesDistintosMeses() {
  130. Mes mes;
  131. TreeMap<Mes, Integer> resultado = new TreeMap<>();
  132. for (int i = 0; i < 12; i++) {
  133. mes = Mes.numero_to_mes(i + 1);
  134. resultado.put(mes, this.numeroClientesDistintosPorMes[i]);
  135. }
  136. return resultado;
  137. }
  138. /*GETTERS CLASSES INFERIORES*/
  139. /*CLASSE FICHA CLIENTE*/
  140. private FichaClienteCompras getFichaClienteNoClone(Cliente cliente) throws ClienteNaoExisteException {
  141. FichaClienteCompras ficha;
  142. if(this.arvoreClientes.containsKey(cliente)){
  143. ficha = this.arvoreClientes.get(cliente);
  144. }else{
  145. throw new ClienteNaoExisteException();
  146. }
  147. return ficha;
  148. }
  149. public int getNumeroProdutosDistintosCliente(Cliente cliente) throws ClienteNaoExisteException {
  150. return this.getFichaClienteNoClone(cliente).getNumeroProdutosDistintos();
  151. }
  152. public Matriz_Int_12x2 getNumeroUnidadesCompradasClienteMeses(Cliente cliente) throws ClienteNaoExisteException {
  153. return this.getFichaClienteNoClone(cliente).getNumUnidadesCompradasClientePorMes();
  154. }
  155. public Matriz_Int_12x2 getNumeroComprasClienteMeses(Cliente cliente) throws ClienteNaoExisteException {
  156. return this.getFichaClienteNoClone(cliente).getNumComprasClientePorMes();
  157. }
  158. public Matriz_Double_12x2 getDinheiroGastoClienteMeses(Cliente cliente) throws ClienteNaoExisteException {
  159. return this.getFichaClienteNoClone(cliente).getDinheiroGastoClientePorMes();
  160. }
  161. public int getNumeroUnidadesCompradasClienteMes(Cliente cliente, Mes mes) throws ClienteNaoExisteException {
  162. return this.getFichaClienteNoClone(cliente).getNumUnidadesCompradasMes(mes, TipoCompra.AMBOS);
  163. }
  164. public int getNumeroComprasClienteMes(Cliente cliente, Mes mes) throws ClienteNaoExisteException {
  165. return this.getFichaClienteNoClone(cliente).getNumComprasMes(mes, TipoCompra.AMBOS);
  166. }
  167. public double getDinheiroGastoClienteMes(Cliente cliente, Mes mes) throws ClienteNaoExisteException {
  168. return this.getFichaClienteNoClone(cliente).getDinheiroGastoClientePorMes(mes, TipoCompra.AMBOS);
  169. }
  170. public int getTotalUnidadesCompradasCliente(Cliente cliente) throws ClienteNaoExisteException {
  171. return this.getFichaClienteNoClone(cliente).getTotalUnidadesCompradas();
  172. }
  173. public int getTotalComprasCliente(Cliente cliente) throws ClienteNaoExisteException {
  174. return this.getFichaClienteNoClone(cliente).getTotalCompras();
  175. }
  176. public double getTotalDinheiroGasto(Cliente cliente) throws ClienteNaoExisteException {
  177. return this.getFichaClienteNoClone(cliente).getTotalDinheiroGasto();
  178. }
  179. /*CLASSE ParProdutoNClientes*/
  180. private ParProdutoNClientes getParProdutoNClientesNoClone(Produto produto) throws ProdutoNaoExisteException {
  181. ParProdutoNClientes resultado;
  182. if(this.arvoreParesProdutoNClientes.containsKey(produto)){
  183. resultado = this.arvoreParesProdutoNClientes.get(produto);
  184. }else{
  185. throw new ProdutoNaoExisteException();
  186. }
  187. return resultado;
  188. }
  189. public int getTotalClientesDistintosProduto(Produto produto) throws ProdutoNaoExisteException {
  190. return this.getParProdutoNClientesNoClone(produto).getNumeroTotalClientesDisntintos();
  191. }
  192. public Map<Mes, Integer> getClientesDistintosProdutoMeses(Produto produto) throws ProdutoNaoExisteException {
  193. return this.getParProdutoNClientesNoClone(produto).getNumeroClientesDistintosPorMes();
  194. }
  195. public int getClientesDistintosProdutoMes(Produto produto, Mes mes) throws ProdutoNaoExisteException {
  196. return this.getParProdutoNClientesNoClone(produto).getNumeroClientesDisntintosMes(mes);
  197. }
  198. /*CLASSE FichaProdutoDeClienteCompras (ASSOCIACAO PRODUTO-CLIENTE)*/
  199. public Matriz_Int_12x2 getComprasProdutoClienteMeses(Produto produto, Cliente cliente) throws ClienteNaoExisteException, ClienteNaoComprouProdutoException {
  200. return this.getFichaClienteNoClone(cliente).getNumComprasProdutoMeses(produto);
  201. }
  202. public Matriz_Int_12x2 getUnidadesCompradasProdutoClienteMeses(Produto produto, Cliente cliente) throws ClienteNaoExisteException, ClienteNaoComprouProdutoException {
  203. return this.getFichaClienteNoClone(cliente).getNumUnidadesCompradasProdutoMeses(produto);
  204. }
  205. public int getTotalComprasProdutoCliente(Produto produto, Cliente cliente) throws ClienteNaoExisteException, ClienteNaoComprouProdutoException{
  206. return this.getFichaClienteNoClone(cliente).getNumTotalUnidadesCompradasProduto(produto);
  207. }
  208. public int getTotalUnidadesCompradasProdutoCliente(Produto produto, Cliente cliente) throws ClienteNaoExisteException, ClienteNaoComprouProdutoException{
  209. return this.getFichaClienteNoClone(cliente).getNumTotalUnidadesCompradasProduto(produto);
  210. }
  211. public double getTotalDinheiroGastoProdutoCliente(Produto produto, Cliente cliente) throws ClienteNaoExisteException, ClienteNaoComprouProdutoException {
  212. return this.getFichaClienteNoClone(cliente).getDinheiroGastoProduto(produto);
  213. }
  214. /*RESULTADOS QUERIES*/
  215. public int getTotalClientesSemCompras() {
  216. int resultado = 0;
  217. for (Map.Entry<Cliente, FichaClienteCompras> entrada : this.arvoreClientes.entrySet()) {
  218. if (entrada.getValue().getTotalCompras() == 0) {
  219. resultado++;
  220. }
  221. }
  222. return resultado;
  223. }
  224. public int getTotalProdutosNaoComprados() {
  225. int resultado = 0;
  226. for (Map.Entry<Produto, ParProdutoNClientes> entrada : this.arvoreParesProdutoNClientes.entrySet()) {
  227. if (entrada.getValue().getNumeroTotalClientesDisntintos() == 0) {
  228. resultado++;
  229. }
  230. }
  231. return resultado;
  232. }
  233. public Map<Mes, Integer> getNumeroProdutosDisntintosPorMesCliente(Cliente cliente) throws ClienteNaoExisteException {
  234. return this.getFichaClienteNoClone(cliente).getNumeroProdutosDistintosPorMes();
  235. }
  236. public List<Produto> getProdutosNaoComprados() {
  237. ArrayList<Produto> lista_produtos = new ArrayList<>();
  238. for (Map.Entry<Produto, ParProdutoNClientes> entrada : this.arvoreParesProdutoNClientes.entrySet()) {
  239. if (entrada.getValue().getNumeroTotalClientesDisntintos() == 0) {
  240. lista_produtos.add(entrada.getKey().clone());
  241. }
  242. }
  243. return lista_produtos;
  244. }
  245. public List<TriploClienteQtdCompradaDinheiro> getTriplosClienteQtdCompradaDinheiro(Produto produto, int topN) {
  246. int unidadesCompradas;
  247. double dinheiroGasto;
  248. TreeSet<TriploClienteQtdCompradaDinheiro> triplos = new TreeSet<>(new ComparatorTriploClienteQtdCompradaDinheiro());
  249. ArrayList<TriploClienteQtdCompradaDinheiro> lista_triplos = new ArrayList<>();
  250. TriploClienteQtdCompradaDinheiro novo_triplo;
  251. for (Map.Entry<Cliente, FichaClienteCompras> entrada : this.arvoreClientes.entrySet()) {
  252. try {
  253. unidadesCompradas = this.getTotalComprasProdutoCliente(produto, entrada.getKey());
  254. dinheiroGasto = this.getTotalDinheiroGastoProdutoCliente(produto, entrada.getKey());
  255. novo_triplo = new TriploClienteQtdCompradaDinheiro(entrada.getKey().clone(),
  256. unidadesCompradas,
  257. dinheiroGasto);
  258. triplos.add(novo_triplo);
  259. } catch (ClienteNaoComprouProdutoException | ClienteNaoExisteException ex) {
  260. }
  261. }
  262. for (TriploClienteQtdCompradaDinheiro triplo : triplos) {
  263. lista_triplos.add(triplo);
  264. }
  265. return lista_triplos.subList(0, (topN > lista_triplos.size()) ? lista_triplos.size() :topN);
  266. }
  267. public List<ParClienteProdutosDiferentes> getParesClienteProdutosDiferentes(int n) {
  268. TreeSet<ParClienteProdutosDiferentes> pares = new TreeSet<>(new ComparatorParClienteProdutosDiferentes());
  269. ArrayList<ParClienteProdutosDiferentes> lista = new ArrayList<>();
  270. ParClienteProdutosDiferentes novo_par;
  271. for (Map.Entry<Cliente, FichaClienteCompras> entrada : this.arvoreClientes.entrySet()) {
  272. novo_par = new ParClienteProdutosDiferentes(entrada.getKey().clone(), entrada.getValue().getNumeroProdutosDistintos());
  273. pares.add(novo_par);
  274. }
  275. for (ParClienteProdutosDiferentes par : pares) {
  276. lista.add(par);
  277. }
  278. if (n > arvoreClientes.size()) {
  279. n = arvoreClientes.size();
  280. }
  281. return lista.subList(0, n);
  282. }
  283. public List<ParProdutoQuantidadeComprada> getParesProdutoNumComprasCliente(Cliente cliente) throws ClienteNaoExisteException {
  284. return this.getFichaClienteNoClone(cliente).getParesProdutoQuantidadeComprada();
  285. }
  286. public List<Cliente> getClientesSemCompras() {
  287. ArrayList<Cliente> lista_clientes = new ArrayList<>(this.arvoreClientes.size() / 10);
  288. for (Map.Entry<Cliente, FichaClienteCompras> entrada : this.arvoreClientes.entrySet()) {
  289. if (entrada.getValue().getTotalCompras() == 0) {
  290. lista_clientes.add(entrada.getKey().clone());
  291. }
  292. }
  293. return (List<Cliente>) lista_clientes;
  294. }
  295. public List<Produto> getProdutosSemCompras() {
  296. ArrayList<Produto> lista_produtos = new ArrayList<>(this.arvoreClientes.size() / 10);
  297. for (Map.Entry<Produto, ParProdutoNClientes> entrada : this.arvoreParesProdutoNClientes.entrySet()) {
  298. if (entrada.getValue().getNumeroTotalClientesDisntintos() == 0) {
  299. lista_produtos.add(entrada.getKey().clone());
  300. }
  301. }
  302. return (List<Produto>) lista_produtos;
  303. }
  304. /*
  305. METODOS STANDARD
  306. */
  307. @Override
  308. public int hashCode() {
  309. int hash = 3;
  310. hash = 11 * hash + this.numeroComprasValorZero;
  311. hash = 11 * hash + Objects.hashCode(this.numeroClientesDistintosPorMes);
  312. hash = 11 * hash + Objects.hashCode(this.arvoreClientes);
  313. hash = 11 * hash + Objects.hashCode(this.arvoreParesProdutoNClientes);
  314. return hash;
  315. }
  316. @Override
  317. public boolean equals(Object obj) {
  318. if (this == obj) {
  319. return true;
  320. }
  321. if (obj == null) {
  322. return false;
  323. }
  324. if (getClass() != obj.getClass()) {
  325. return false;
  326. }
  327. final Compras other = (Compras) obj;
  328. return this.arvoreClientes.size() == other.arvoreClientes.size()
  329. && this.arvoreParesProdutoNClientes.size() == other.arvoreParesProdutoNClientes.size()
  330. && Arrays.equals(this.numeroClientesDistintosPorMes, other.numeroClientesDistintosPorMes)
  331. && this.numeroComprasValorZero == other.numeroComprasValorZero;
  332. }
  333. @Override
  334. public String toString() {
  335. StringBuilder sb = new StringBuilder();
  336. sb.append("Compras{");
  337. sb.append("Compras valor zero=").append(numeroComprasValorZero);
  338. sb.append(" Nº Clientes distintos=").append(arvoreClientes.size());
  339. sb.append('}');
  340. return sb.toString();
  341. }
  342. public Compras clone() {
  343. return new Compras(this);
  344. }
  345. }