Java - como consultar y organizar por categorias (Eercicio en java)

 
Vista:

como consultar y organizar por categorias (Eercicio en java)

Publicado por juan (1 intervención) el 11/10/2022 19:12:11
buen dia,
como puedo hacer este ejercicio, consultar y organizar por categoria,supongo que es un estilo filtro o algo similar


//Crear un carrito de compras donde se pueda añadir diferentes productos
// y poder consultarlos todos, consultarlos por categoría,
// estos productos se deben poder ordenar por precio, por categoría y por nombre//
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de Kabuto
Val: 3.428
Oro
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

como consultar y organizar por categorias (Eercicio en java)

Publicado por Kabuto (1381 intervenciones) el 12/10/2022 13:58:41
Hola.

Lo primero, necesitamos una clase Producto. Algo sencillo: constructor, getters (setters no harán falta) y un método toString()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class Producto {
 
	private String nombre;
	private String categoria;
	private double precio;
 
	public Producto(String nombre, String categoria, double precio) {
		this.nombre = nombre;
		this.categoria = categoria;
		this.precio = precio;
	}
 
	@Override
	public String toString() {
		return String.format("--> %-30s\t%-15s\t%.2f", nombre, categoria.toUpperCase(), precio);
	}
 
	public String getNombre() {
		return nombre;
	}
 
	public String getCategoria() {
		return categoria;
	}
 
	public double getPrecio() {
		return precio;
	}
 
}


Lo siguiente, una clase Carrito.
Esta clase tendrá un ArrayList de objetos Producto y será ella quien se encargue de ordenar los productos y filtrar según una categoría indicada por el usuario.
1
2
3
public class Carrito {
 
	private ArrayList<Producto> compra = new ArrayList<Producto>();
Para ordenar los productos, podemos usar objetos de la clase Comparator.
Mediante estos objetos, podemos decirle a un ArrayList cómo deseamos que ordene los objetos que contiene.
Como hay tres atributos distintos por los que podemos ordenar: nombre, categoria y precio pues escribiremos tres clases Comparator y en cada una ordenaremos por un atributo o por otro.
Por ejemplo, para ordenar "por nombre", escribiríamos esta clase Comparator en la que indicamos que el orden ha de ser el resultado de comparar el atributo nombre:
1
2
3
4
5
6
private class PorNombre implements Comparator<Producto> {
		@Override
		public int compare(Producto o1, Producto o2) {
			return o1.getNombre().compareTo(o2.getNombre());
		}
	}

De esta manera, si simplemente queremos listar el carrito, sin ningún orden específico, lo haríamos así:
1
2
3
4
public void listarCompra() {
		System.out.println("\n\t\tLista de compra\n");
		compra.forEach(System.out::println);
	}

Y si queremos que se muestren ordenados. Tenemos dos posibilidades.
Una, ordenar el ArrayList original y listarlo en pantalla:
1
2
3
4
5
public void listarPorNombre() {
		System.out.println("\n\t\tOrdenados por Nombre\n");
		compra.sort(new PorNombre());
		compra.forEach(System.out::println);
	}

Dos, si no queremos modificar el orden del ArrayList original, podemos crear un stream a partir de él. Y será este stream el que ordenaremos y listaremos en pantalla:
1
2
3
4
public void listarPorNombre() {
		System.out.println("\n\t\tOrdenados por Nombre\n");
		compra.stream().sorted(new PorNombre()).forEach(System.out::println);
	}

En cuanto al "filtrado".
Podríamos simplemente recorrer el ArrayList y mostrar solo los objetos que coincidan con la categoría:
1
2
3
4
5
6
7
8
9
10
public void filtrarPorCategoria(String categoria) {
		System.out.println("\n\tFiltrado por: " + categoria + "\n");
		int contador = 0;
		for (Producto prod: compra)
			if (prod.getCategoria().equals(categoria))
				System.out.println(prod);
 
		if (contador == 0)
			System.out.println("\nNo hay productos para esta categoria.");
	}

Con esto sería suficiente, ya que es un filtrado sencillo.

Si el filtrado fuera más complejo (hubiera que tener en cuenta varios atributos), entonces vamos a preferir formas más avanzadas y para ello en Java tenemos los "predicados" (interfaz Predicate).
Podríamos escribir una clase, al estilo de lo que hemos hecho con los Comparator, para establecer las reglas de filtrado que queremos aplicar.

Pero como en esta ocasión el filtrado es sencillo, podemos aplicar el predicado directamente con una expresión lambda.
De nuevo haremos un stream a partir del ArrayList original que esta vez contendrá solo los objetos que coincidan con el filtro indicado.
Para poder saber si hemos encontrado objetos o no que cumplan el filtro, esta vez en lugar de mostrar en pantalla directamente el stream lo que haremos será crear un nuevo ArrayList con él.
Así podremos comprobar si dicho ArrayList tiene objetos o está vacío, y así informar apropiadamente en pantalla:
1
2
3
4
5
6
7
8
9
public void filtrarPorCategoria(String categoria) {
		System.out.println("\n\tFiltrado por: " + categoria + "\n");
		ArrayList<Producto> filtrado = (ArrayList<Producto>) compra.stream().filter(producto -> producto.getCategoria().equals(categoria)).collect(Collectors.toList());
 
		if (filtrado.isEmpty())
			System.out.println("\nNo hay productos para esta categoria.");
		else
			filtrado.stream().forEach(System.out::println);
	}


Bueno, pues tras explicar todo esto, esta podría ser la clase Carrito completa y definitiva.
Fíjate que en el constructor ya añado unos cuantos Producto, esto es para poder hacer pruebas sin tener que introducir a mano nuevos productos cada vez que iniciamos el programa:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
public class Carrito {
 
	private ArrayList<Producto> compra = new ArrayList<Producto>();
 
	public Carrito() {
		//Para que sea más cómodo testear, añadimos por código unos cuantos productos
		compra.add(new Producto("Patatas Buena Tierra 1kg", "Alimentacion", 2.34));
		compra.add(new Producto("Pato W.C. 500ml", "Limpieza", 3.25));
		compra.add(new Producto("Pack 6 latas CocaCola", "Bebidas", 4.95));
		compra.add(new Producto("Bastoncillos Algodon", "Higiene", 1.75));
		compra.add(new Producto("Zanahorias La Liebre 750g", "Alimentacion", 1.45));
		compra.add(new Producto("Calamares Findus 2kg", "Congelados", 3.80));
		compra.add(new Producto("Lejia Brillante 1l", "Limpieza", 3.15));
		compra.add(new Producto("Atun del Norte lata 350g", "Alimentacion", 4.99));
		compra.add(new Producto("Agua Fuente Mágica 5l", "Bebidas", 3.45));
		compra.add(new Producto("Toallitas Humedas CuloSano", "Higiene", 4.00));
		compra.add(new Producto("Mocho y palo fregona", "Limpieza", 5.65));
	}
 
	public void addProducto(Producto p) {
		compra.add(p);
	}
 
	public void listarCompra() {
		System.out.println("\n\t\tLista de compra\n");
		compra.forEach(System.out::println);
	}
 
	public void listarPorNombre() {
		System.out.println("\n\t\tOrdenados por Nombre\n");
		compra.stream().sorted(new PorNombre()).forEach(System.out::println);
	}
 
	public void listarPorCategoria() {
		System.out.println("\n\t\tOrdenados por Categoria\n");
		compra.stream().sorted(new PorCategoria()).forEach(System.out::println);
	}
 
	public void listarPorPrecio() {
		System.out.println("\n\t\tOrdenados por Precio\n");
		compra.stream().sorted(new PorPrecio()).forEach(System.out::println);
	}
 
	public void filtrarPorCategoria(String categoria) {
		System.out.println("\n\tFiltrado por: " + categoria + "\n");
		ArrayList<Producto> filtrado = (ArrayList<Producto>) compra.stream().filter(producto -> producto.getCategoria().equals(categoria)).collect(Collectors.toList());
 
		if (filtrado.isEmpty())
			System.out.println("\nNo hay productos para esta categoria.");
		else
			filtrado.stream().forEach(System.out::println);
	}
 
	//Clases comparators para ordenar
	private class PorNombre implements Comparator<Producto> {
		@Override
		public int compare(Producto o1, Producto o2) {
			return o1.getNombre().compareTo(o2.getNombre());
		}
	}
 
	private class PorCategoria implements Comparator<Producto> {
		@Override
		public int compare(Producto o1, Producto o2) {
			return o1.getCategoria().compareTo(o2.getCategoria());
		}
	}
 
	private class PorPrecio implements Comparator<Producto> {
		@Override
		public int compare(Producto o1, Producto o2) {
			return Double.compare(o1.getPrecio(), o2.getPrecio());
		}
	}
 
}


Y ahora solo queda hacer la clase Main.
Aquí tendremos nuestro Carrito listo para que el usuario, mediante un menú, pueda añadir más productos, listarlos según atributos y filtrar por la categoría deseada:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
public class Main {
 
	private static Carrito carritoCompra = new Carrito();
	private static Scanner teclado = new Scanner(System.in);
 
	public static void main(String[] args) {
 
		String opcion = "";
		do {
			System.out.println("\n\t\tCARRITO DE COMPRA");
			System.out.println("\t\t------- -- ------\n");
			System.out.println("[1] -- Añadir producto");
			System.out.println("[2] -- Listar Compra");
			System.out.println("[3] -- Ordenar por Nombre");
			System.out.println("[4] -- Ordenar por Categoria");
			System.out.println("[5] -- Ordenar por Precio");
			System.out.println("[6] -- Filtrar por Categoria");
			System.out.println("[0] -- TERMINAR");
			System.out.print("Opcion: ");
			opcion = teclado.nextLine();
 
			switch(opcion) {
				case "0":
					System.out.println("\n\t\tFIN DE PROGRAMA");
					break;
				case "1":
					System.out.println("\n\tAñadir Producto");
					System.out.print("Nombre: ");
					String nombre = teclado.nextLine();
					System.out.print("Categoria: ");
					String categoria = teclado.nextLine();
					System.out.print("Precio: ");
					double precio = Double.parseDouble(teclado.nextLine());
					carritoCompra.addProducto(new Producto(nombre, categoria, precio));
					break;
				case "2":
					carritoCompra.listarCompra();
					break;
				case "3":
					carritoCompra.listarPorNombre();
					break;
				case "4":
					carritoCompra.listarPorCategoria();
					break;
				case "5":
					carritoCompra.listarPorPrecio();
					break;
				case "6":
					System.out.println("\n\tFiltrar por categoria");
					System.out.print("Categoria: ");
					String filtro = teclado.nextLine();
					carritoCompra.filtrarPorCategoria(filtro);
					break;
				default:
					System.out.println("\nOpción equivocada");
 
			}
		} while(!opcion.equals("0"));
 
	}
 
}


Lo importante es comprender cómo hemos empleado la interfaz Comparator para crear clases que permiten ordenar una colección de distintas formas.
Y lo mismo con la interfaz Predicate, que en esta ocasión la hemos aplicado mediante una expresión lambda, lo cuál permite ahorrar mucho código.

Es decir, esta expresión que marco en negrita:
1
compra.stream().filter(producto -> producto.getCategoria().equals(categoria))

Nos ha evitado tener que escribir una clase completa como esta:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
private class Filtro implements Predicate<Producto> {
 
		private String categoria;
 
		public Filtro(String categoria) {
			this.categoria = categoria;
		}
 
		@Override
		public boolean test(Producto prod) {
			return prod.getCategoria().equals(categoria);
		}
 
	}
 
	public void filtrarPorCategoria(String categoria) {
		System.out.println("\n\tFiltrado por: " + categoria + "\n");
		ArrayList<Producto> filtrado = (ArrayList<Producto>) compra.stream().filter(new Filtro(categoria)).collect(Collectors.toList());
 
		if (filtrado.isEmpty())
			System.out.println("\nNo hay productos para esta categoria.");
		else
			filtrado.stream().forEach(System.out::println);
	}


Y nada más que añadir.
Espero que se haya entendido. Pregunta lo que necesites.
Un saludo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de juan

como consultar y organizar por categorias (Eercicio en java)

Publicado por juan (18 intervenciones) el 13/10/2022 03:57:13
super!! Muchas gracias por tu ayuda, genialy !!
Tengo una duda para añadir un metodo de caja (en la que se muestre el valor total de los productos con iva,y total con iva) estoy intentando crear un metodo en la class carrito t en main un case que muestre caja , pero no me sale :

CLASS CARRITO
public double comprar () {
int indice =0;
double indice2 =0;
System.out.print("\n\t\tEl total de la caja es: ");
for (int i=0; i <compra.size();i++) {
indice=compra.get(i).()+indice;
}
System.out.println("Total de compra: "+indice);
indice2= indice*0.19;
System.out.println("iva "+indice2);
System.out.println("total compra mas iva"+ (indice+indice2));


CLASS MAIN

case "7":
System.out.println( "\n\t Caja");
carrodecompra.comprar();
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Kabuto
Val: 3.428
Oro
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

como consultar y organizar por categorias (Eercicio en java)

Publicado por Kabuto (1381 intervenciones) el 13/10/2022 20:44:28
Parece que donde marco en negrita falta llamar al método getPrecio(), ¿no?

1
2
3
4
5
6
7
8
9
10
11
public double comprar () {
int indice =0;
double indice2 =0;
System.out.print("\n\t\tEl total de la caja es: ");
for (int i=0; i <compra.size();i++) {
indice=compra.get(i).()+indice;
}
System.out.println("Total de compra: "+indice);
indice2= indice*0.19;
System.out.println("iva "+indice2);
System.out.println("total compra mas iva"+ (indice+indice2));

Además si usas un "for each" en lugar de un for "normal", el código puede quedar un poco más compacto:
1
2
3
4
5
6
7
8
9
10
public void comprar() {
		double sumaImportes = 0;
		for (Producto prod: compra)
			sumaImportes += prod.getPrecio();
		double iva = sumaImportes * 0.19;
		System.out.println("\n\t\tEl total de la caja es: ");
		System.out.println("Total de compra: "+ sumaImportes);
		System.out.println("Iva: " + iva);
		System.out.println("Total compra más IVA: " + (sumaImportes + iva));
	}

Si lo probamos funciona, pero pueden salir números muy feos, con muchos decimales:
1
2
3
4
5
6
Opcion: 7
 
		El total de la caja es:
Total de compra: 38.779999999999994
Iva: 7.368199999999999
Total compra más IVA: 46.148199999999996

Esto podemos usarlo con printf(), para dar "formato" al texto y pedir que redondee los valores a solo dos decimales:
1
2
3
4
5
6
7
8
9
10
public void comprar() {
		double sumaImportes = 0;
		for (Producto prod: compra)
			sumaImportes += prod.getPrecio();
		double iva = sumaImportes * 0.19;
		System.out.println("\n\t\tEl total de la caja es: ");
		System.out.printf("Total de compra: %.2f\n", sumaImportes);
		System.out.printf("Iva: %.2f\n", iva);
		System.out.printf("Total compra más IVA: %.2f\n", (sumaImportes + iva));
	}

Ahora sí queda más elegante:
1
2
3
4
5
6
Opcion: 7
 
		El total de la caja es:
Total de compra: 38,78
Iva: 7,37
Total compra más IVA: 46,15
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

como consultar y organizar por categorias (Eercicio en java)

Publicado por juan (1 intervención) el 14/10/2022 14:34:50
muchas gracias por tu ayuda, me sirvió mucho ..
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar