Java - Optimización: ¿Cómo repetir partes de código?

 
Vista:
sin imagen de perfil
Val: 20
Ha aumentado su posición en 20 puestos en Java (en relación al último mes)
Gráfica de Java

Optimización: ¿Cómo repetir partes de código?

Publicado por Rodrigo (10 intervenciones) el 13/05/2021 00:15:31
Qué tal, buenas tardes, les platico lo que quiero hacer.
Hace poco realicé un programa el cual a partir de un archivo de de texto, tenía que dividirlo por partes o secciones y a partir de eso por medio de un .substring cortar y convertir los valores para realizar una suma. Adjunto un bloque de código para que lo entiendan:


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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
if(linea.contains("SEG.DE SALUD PENSIONADOS   ART.42  0.625% ")){
 
    //CONCEPTO
    concepto4 = linea.substring(0,42);
    //System.out.println(concepto);
 
    //CASOS NOMINA ORDINARIA
    casosNomOrdinaria = linea.substring(58,64);
    casosNomOrdinaria = casosNomOrdinaria.replaceAll(",", "").trim();
    sumaCasos = Integer.parseInt(casosNomOrdinaria);
    temp = sumaCasos;
    suma41 = temp + suma41;
    //System.out.println(casosNomOrdinaria);
 
    //NOMINA ORDINARIA
    nominaOrdinaria = linea.substring(67,84);
    nominaOrdinaria = nominaOrdinaria.replaceAll(",", "").trim();
    sumaCasos1 = Double.parseDouble(nominaOrdinaria);
    temp1 = sumaCasos1;
    suma45 = temp1 + suma45;
   // System.out.println(nominaOrdinaria);
 
    //CASOS PAGOS CANCELADOS
    casosPagosCancelados = linea.substring(86,94).trim();
    sumaCasos2 = Integer.parseInt(casosPagosCancelados);
    temp2 = sumaCasos2;
    suma42 = temp2 + suma42;
    //System.out.println(casosPagosCancelados);
 
    //PAGOS CANCELADOS
    pagosCancelados = linea.substring(97,114);
    pagosCancelados = pagosCancelados.replaceAll(",","").trim();
    sumaCasos3 = Double.parseDouble(pagosCancelados);
    temp3 = sumaCasos3;
    suma46 = temp3 + suma46;
    //System.out.println(pagosCancelados);
 
    //CASOS NOMINA EXTRAORDINARIA
    casosNomExt = linea.substring(117,124);
    casosNomExt = casosNomExt.replaceAll(",","").trim();
    sumaCasos4 = Integer.parseInt(casosNomExt);
    temp4 = sumaCasos4;
    suma43 = temp4 + suma43;
    //System.out.println(casosNomExt);
 
    //NOMINA EXTRAORDINARIA
    NomExt = linea.substring(127, 144);
    NomExt = NomExt.replaceAll(",","").trim();
    sumaCasos5 = Double.parseDouble(NomExt);
    temp5 = sumaCasos5;
    suma47 = temp5 + suma47;
    //System.out.println(NomExt);
 
    //TOTAL CASOS
    totalCasos = linea.substring(147,156);
    totalCasos = totalCasos.replaceAll(",","").trim();
    sumaCasos6 = Integer.parseInt(totalCasos);
    temp6 = sumaCasos6;
    suma44 = temp6 + suma44;
    //System.out.println(totalCasos);
 
    //TOTAL
    totalFinal = linea.substring(160, 177);
    totalFinal = totalFinal.replaceAll(",","").trim();
    sumaCasos7 = Double.parseDouble(totalFinal);
    temp7 = sumaCasos7;
    suma48 = temp7 + suma48;
    //System.out.println(totalFinal);
}
if(linea.contains("RETIRO EDAD AVANZADA/VEJEZ ART.102 6.125% ")){
 
    //CONCEPTO
    concepto5 = linea.substring(0,42);
    //System.out.println(concepto);
 
    //CASOS NOMINA ORDINARIA
    casosNomOrdinaria = linea.substring(58,64);
    casosNomOrdinaria = casosNomOrdinaria.replaceAll(",", "").trim();
    sumaCasos = Integer.parseInt(casosNomOrdinaria);
    temp = sumaCasos;
    suma51 = temp + suma51;
    //System.out.println(casosNomOrdinaria);
 
    //NOMINA ORDINARIA
    nominaOrdinaria = linea.substring(67,84);
    nominaOrdinaria = nominaOrdinaria.replaceAll(",", "").trim();
    sumaCasos1 = Double.parseDouble(nominaOrdinaria);
    temp1 = sumaCasos1;
    suma55 = temp1 + suma55;
   // System.out.println(nominaOrdinaria);
 
    //CASOS PAGOS CANCELADOS
    casosPagosCancelados = linea.substring(86,94).trim();
    sumaCasos2 = Integer.parseInt(casosPagosCancelados);
    temp2 = sumaCasos2;
    suma52 = temp2 + suma52;
    //System.out.println(casosPagosCancelados);
 
    //PAGOS CANCELADOS
    pagosCancelados = linea.substring(97,114);
    pagosCancelados = pagosCancelados.replaceAll(",","").trim();
    sumaCasos3 = Double.parseDouble(pagosCancelados);
    temp3 = sumaCasos3;
    suma56 = temp3 + suma56;
    //System.out.println(pagosCancelados);
 
    //CASOS NOMINA EXTRAORDINARIA
    casosNomExt = linea.substring(117,124);
    casosNomExt = casosNomExt.replaceAll(",","").trim();
    sumaCasos4 = Integer.parseInt(casosNomExt);
    temp4 = sumaCasos4;
    suma53 = temp4 + suma53;
    //System.out.println(casosNomExt);
 
    //NOMINA EXTRAORDINARIA
    NomExt = linea.substring(127, 144);
    NomExt = NomExt.replaceAll(",","").trim();
    sumaCasos5 = Double.parseDouble(NomExt);
    temp5 = sumaCasos5;
    suma57 = temp5 + suma57;
    //System.out.println(NomExt);
 
    //TOTAL CASOS
    totalCasos = linea.substring(147,156);
    totalCasos = totalCasos.replaceAll(",","").trim();
    sumaCasos6 = Integer.parseInt(totalCasos);
    temp6 = sumaCasos6;
    suma54 = temp6 + suma54;
    //System.out.println(totalCasos);
 
    //TOTAL
    totalFinal = linea.substring(160, 177);
    totalFinal = totalFinal.replaceAll(",","").trim();
    sumaCasos7 = Double.parseDouble(totalFinal);
    temp7 = sumaCasos7;
    suma58 = temp7 + suma58;
    //System.out.println(totalFinal);
}
if(linea.contains("SEG.INVALIDEZ Y VIDA       ART.140 0.625% ")){
 
    //CONCEPTO
    concepto6 = linea.substring(0,42);
    //System.out.println(concepto);
 
    //CASOS NOMINA ORDINARIA
    casosNomOrdinaria = linea.substring(58,64);
    casosNomOrdinaria = casosNomOrdinaria.replaceAll(",", "").trim();
    sumaCasos = Integer.parseInt(casosNomOrdinaria);
    temp = sumaCasos;
    suma61 = temp + suma61;
    //System.out.println(casosNomOrdinaria);
 
    //NOMINA ORDINARIA
    nominaOrdinaria = linea.substring(67,84);
    nominaOrdinaria = nominaOrdinaria.replaceAll(",", "").trim();
    sumaCasos1 = Double.parseDouble(nominaOrdinaria);
    temp1 = sumaCasos1;
    suma65 = temp1 + suma65;
   // System.out.println(nominaOrdinaria);
 
    //CASOS PAGOS CANCELADOS
    casosPagosCancelados = linea.substring(86,94).trim();
    sumaCasos2 = Integer.parseInt(casosPagosCancelados);
    temp2 = sumaCasos2;
    suma62 = temp2 + suma62;
    //System.out.println(casosPagosCancelados);
 
    //PAGOS CANCELADOS
    pagosCancelados = linea.substring(97,114);
    pagosCancelados = pagosCancelados.replaceAll(",","").trim();
    sumaCasos3 = Double.parseDouble(pagosCancelados);
    temp3 = sumaCasos3;
    suma66 = temp3 + suma66;
    //System.out.println(pagosCancelados);
 
    //CASOS NOMINA EXTRAORDINARIA
    casosNomExt = linea.substring(117,124);
    casosNomExt = casosNomExt.replaceAll(",","").trim();
    sumaCasos4 = Integer.parseInt(casosNomExt);
    temp4 = sumaCasos4;
    suma63 = temp4 + suma63;
    //System.out.println(casosNomExt);
 
    //NOMINA EXTRAORDINARIA
    NomExt = linea.substring(127, 144);
    NomExt = NomExt.replaceAll(",","").trim();
    sumaCasos5 = Double.parseDouble(NomExt);
    temp5 = sumaCasos5;
    suma67 = temp5 + suma67;
    //System.out.println(NomExt);
 
    //TOTAL CASOS
    totalCasos = linea.substring(147,156);
    totalCasos = totalCasos.replaceAll(",","").trim();
    sumaCasos6 = Integer.parseInt(totalCasos);
    temp6 = sumaCasos6;
    suma64 = temp6 + suma64;
    //System.out.println(totalCasos);
 
    //TOTAL
    totalFinal = linea.substring(160, 177);
    totalFinal = totalFinal.replaceAll(",","").trim();
    sumaCasos7 = Double.parseDouble(totalFinal);
    temp7 = sumaCasos7;
    suma68 = temp7 + suma68;
    //System.out.println(totalFinal);
}

En sí el proceso es el mismo para todos los apartados.
Necesito saber si alguien puede orientarme para optimizar este código.
No busco que lo resuelvan, sencillamente que me orienten a decirme por medio de qué puedo hacerlo.

Al final imprimo los resultados en una variable distinta para cada resultado así:


1
2
3
wr.printf("%-52s %9d\t $%17s %9d \t$%17s %9d \t$%17s %9d \t$%17s %n",concepto,sumaTotal,formato.format(sumaTotal1),sumaTotal2,formato.format(sumatotal3),sumaTotal4,formato.format(sumaTotal5),sumaTotal6,formato.format(sumaTotal7));
wr.printf("%-52s %9d\t $%17s %9d \t$%17s %9d \t$%17s %9d \t$%17s %n",concepto2,suma21,formato.format(suma25),suma22,formato.format(suma26),suma23,formato.format(suma27),suma24,formato.format(suma28));
wr.printf("\n");

Tengo una ligera idea y se me había ocurrido hacer un método para cada apartado.
De antemano, ¡Muchas gracias por leerme!
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

Optimización: ¿Cómo repetir partes de código?

Publicado por Kabuto (1381 intervenciones) el 13/05/2021 02:51:03
Bueno, para empezar creo que tienes un montón de variables innecesarias.

Por ejemplo, estas líneas que marco en negrita:
1
2
3
4
5
6
//NOMINA EXTRAORDINARIA
NomExt = linea.substring(127, 144);
NomExt = NomExt.replaceAll(",","").trim();
sumaCasos5 = Double.parseDouble(NomExt);
temp5 = sumaCasos5;
suma47 = temp5 + suma47;

¿No te funcionaría igual si lo escribes así?

1
2
3
4
//NOMINA EXTRAORDINARIA
NomExt = linea.substring(127, 144);
NomExt = NomExt.replaceAll(",","").trim();
suma47 +=  Double.parseDouble(NomExt);

Pues dicho cambio lo podrías hacer en todos los párrafos donde haces sumas, ahorrando bastante líneas de código y teniendo que usar menos variables.


Al margen de esto, podría ser muy útil usar programación orientada a objetos (POO) en este caso (bueno, en este caso y en todos)

A ver, sin conocer el resto del programa, ni ver como es el archivo de texto, ni tener más información... solo puedo especular.
Y especulo que el archivo de texto tiene líneas que comienzan indicando distintos conceptos.
Como por ejemplo: "SEG.INVALIDEZ Y VIDA ART.140 0.625% "

Para cada uno de estos conceptos, tenemos unos valores enteros: nominas ordinarias, pagos cancelados, nominas extraordinarias y casos.
Y también unos valores double, que serían los importes de esas nominas, pagos, casos, etc...

Bien, pues se puede crear una clase llamada Concepto.
Con unos atributos que sean el nombre específico del Concepto y esos valores int y double.

Y como todas las líneas de texto se procesan igual, solo cambia a que Concepto hay que asignarle los valores que se extraen, pues esta clase tendrá un método que recibirá una línea de texto para procesar y asignar los valores a los atributos de la clase.

También le podemos dar un método llamado toString(), para mostrar en pantalla los valores de los atributos formateados.

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
public class Concepto {
 
	private String nombreConcepto;
	private int nominasOrdinarias;
	private double sumaNominasOrd;
	private int pagosCancelados;
	private double sumaPagosCancel;
	private int nominasExtraOrdinarias;
	private double sumaNominasExtra;
	private int casos;
	private double sumaCasos;
 
	public Concepto(String nombre) {
		nombreConcepto = nombre;
	}
 
	public String getConcepto() {
		return nombreConcepto;
	}
 
	public void procesarLinea(String linea) {
		//CASOS NOMINA ORDINARIA
		String casosNomOrdinaria = linea.substring(58,64);
		casosNomOrdinaria = casosNomOrdinaria.replaceAll(",", "").trim();
		nominasOrdinarias += Integer.parseInt(casosNomOrdinaria);
 
		casosNomOrdinaria = linea.substring(67,84);
		casosNomOrdinaria = casosNomOrdinaria.replaceAll(",", "").trim();
		sumaNominasOrd += Double.parseDouble(casosNomOrdinaria);
 
		//CASOS PAGOS CANCELADOS
		String casosPagosCancelados = linea.substring(86,94).trim();
		pagosCancelados += Integer.parseInt(casosPagosCancelados);
 
		casosPagosCancelados = linea.substring(97,114);
		casosPagosCancelados = casosPagosCancelados.replaceAll(",","").trim();
		sumaPagosCancel += Double.parseDouble(casosPagosCancelados);
 
		//CASOS NOMINA EXTRAORDINARIA
		String casosNomExt = linea.substring(117,124);
		casosNomExt = casosNomExt.replaceAll(",","").trim();
		nominasExtraOrdinarias += Integer.parseInt(casosNomExt);
 
		casosNomExt = linea.substring(127, 144);
		casosNomExt = casosNomExt.replaceAll(",","").trim();
		sumaNominasExtra += Double.parseDouble(casosNomExt);
 
		//TOTAL CASOS
		String totalCasos = linea.substring(147,156);
		totalCasos = totalCasos.replaceAll(",","").trim();
		casos += Integer.parseInt(totalCasos);
 
		totalCasos = linea.substring(160, 177);
		totalCasos = totalCasos.replaceAll(",","").trim();
		sumaCasos += Double.parseDouble(totalCasos);
 
	}
 
	@Override
	public String toString() {
		return String.format("%-52s %9d\t $%17.2f %9d \t$%17.2f %9d \t$%17.2f %9d \t$%17.2f %n",
				nombreConcepto, nominasOrdinarias, sumaNominasOrd, pagosCancelados, sumaPagosCancel,
				nominasExtraOrdinarias, sumaNominasExtra, casos, sumaCasos);
	}
 
}

Teniendo esta clase, en el programa principal, podemos crear un objeto Concepto por cada concepto existente (no se cuantos son)

O mejor aún, crear un array de tipo Concepto, para así tenerlos todos agrupados en una colección.

He escrito este programa principal, con un array donde inicializo tres conceptos. Solo pongo tres porque son los que veo en tu código, pero especulo con que son más.
A cada concepto le doy un nombre que (especulo) coincide con el comienzo de las líneas del archivo.

Luego escribo un código que lee líneas del archivo y analizando los primeros 41 caracteres, decido a que Concepto pertenece. Y a dicho objeto Concepto, le paso la línea para que la procese con el método que ya tiene escrito en su clase.

Luego, tras terminar de leer el archivo, recorro todo el array con un for each para mostrar los datos capturados.

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
public class LeerConceptos {
 
	private static Concepto[] conceptos; //Array para los objetos Concepto
 
	public static void main(String[] args) {
 
		//Inicializamos array de conceptos
		conceptos = new Concepto[3];
		conceptos[0] = new Concepto("SEG.DE SALUD PENSIONADOS   ART.42  0.625% ");
		conceptos[1] = new Concepto("RETIRO EDAD AVANZADA/VEJEZ ART.102 6.125% ");
		conceptos[2] = new Concepto("SEG.INVALIDEZ Y VIDA       ART.140 0.625% ");
 
		//Lectura de archivo texto
		try {
			BufferedReader br = new BufferedReader(new FileReader("conceptos.txt"));
			String linea = br.readLine();
			while (linea != null) {
				//Analizamos comienzo de linea para decidir que CONCEPTO ha de procesar linea
				String concepto = linea.substring(0,42);
				if (concepto.equals(conceptos[0].getConcepto()))
					conceptos[0].procesarLinea(linea);
				else if (concepto.equals(conceptos[1].getConcepto()))
					conceptos[1].procesarLinea(linea);
				else if (concepto.equals(conceptos[2].getConcepto()))
					conceptos[2].procesarLinea(linea);
 
				//Linea procesada, pasamos a la siguiente
				linea = br.readLine();
			}
		} catch (FileNotFoundException e) {
			System.out.println("Archivo no encontrado");
		} catch (IOException e) {
			System.out.println("Error de lectura.");
		}
 
		//Lectura del archivo ha finalizado, mostramos los datos capturados en el array
 
		for (Concepto concep: conceptos)
			System.out.println(concep);
 
	}
 
}


Como no tengo el archivo de texto, no he podido probarlo. Pero en teoría funciona. En cualquier caso, puede servirte de inspiración para adaptarlo y hacer que funcione, si es que me he equivocado en alguna de mis especulaciones je je...

Como ves, usando POO, se escribe menos código y además es más fácil reutilizarlo. Escribiendo una única clase, se puede computar tantos Conceptos como puedan existir en el archivo de texto
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar
sin imagen de perfil
Val: 20
Ha aumentado su posición en 20 puestos en Java (en relación al último mes)
Gráfica de Java

Optimización: ¿Cómo repetir partes de código?

Publicado por Rodrigo (10 intervenciones) el 14/05/2021 21:07:14
Muchas gracias, estoy trabajando en ello.
En cuanto termine, lo subo por acá.
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
sin imagen de perfil
Val: 20
Ha aumentado su posición en 20 puestos en Java (en relación al último mes)
Gráfica de Java

Optimización: ¿Cómo repetir partes de código?

Publicado por Rodrigo (10 intervenciones) el 19/05/2021 20:24:21
Logré hacer que funcionara, tengo otros detalles que aún estoy solucionando porque, como mencionas, no subí mi archivo.
Sólo no comprendo este método:

1
2
3
4
5
6
@Override
public String toString() {
	return String.format("%-52s %9d\t $%17.2f %9d \t$%17.2f %9d \t$%17.2f %9d \t$%17.2f %n",
	nombreConcepto, nominasOrdinarias, sumaNominasOrd, pagosCancelados, sumaPagosCancel,
	nominasExtraOrdinarias, sumaNominasExtra, casos, sumaCasos);
}

En qué parte del código se llama a este método? O estoy entendiendo mal alguna parte. Muchas gracias amigo, me sirvió de mucho tu código.
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

Optimización: ¿Cómo repetir partes de código?

Publicado por Kabuto (1381 intervenciones) el 20/05/2021 01:33:10
Hola.
Sí, ese método, aunque no se vea, lo estamos llamando aquí:

1
2
3
4
//Lectura del archivo ha finalizado, mostramos los datos capturados en el array
 
for (Concepto concep: conceptos)
    System.out.println(concep);

El método toString(), lo que hace posible es que un objeto pueda construir y retornar un String con los datos y formato que nosotros queremos que represente a ese objeto.
Cada "concepto" es capaz de generar el String que le representa.

Entonces, dicho String podemos pasárselo por ejemplo al método println() para que lo muestre en pantalla:

1
2
3
4
//Lectura del archivo ha finalizado, mostramos los datos capturados en el array
 
for (Concepto concep: conceptos)
    System.out.println(concep.toString());

Pero resulta, que println(), y algunos otros métodos de Java, son muy listos y cuando reciben un objeto que NO es un String, ya se encargan ellos de comprobar si dicho objeto posee un método toString() y muestran lo que este les devuelva.

Así que para println() no hace falta que el objeto que queremos mostrar invoque su método toString(). Va a funcionar igual si lo ponemos o no, porque println() ya se hace cargo.

Así que, aunque no esté escrito en el código, aquí también se está usando el método toString()

1
2
3
4
//Lectura del archivo ha finalizado, mostramos los datos capturados en el array
 
for (Concepto concep: conceptos)
    System.out.println(concep); //Equivale a concep.toString()
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