Ejercicios Parcial Java
Ejercicios Parcial Java
PARCIAL JAVA
Olivia Gallego Toscano
Tema 1:
Ej1: contador de segundos de una fecha dada………………………p.1
Ej2: max de int, char, short………………………………………….p.2
Ej3: array múltiplos de 5 y suma de ellos…………………………..p.2
Ej4: max y min de una lista…………………………………………p.3
Ej5: tablas de multiplicar……………………………………………p.5
Ej6: N primeros nº primos de una lista………………………………p.6
Ej7: descomponer nº en factores primos……………………………..p.7
Ej8: media, max, min, de un array de nº……………………………..p.8-9
Ej9: vectores y producto escalar……………………………………..p.10-11
Ej10: matriz cuadrada con nº aleatorios……………………………..p.12
Ej11: multiplicar matrices……………………………………………p.13-14
Ej12: contar vocales de en una cadena de caracteres………………..p.15
Ej13: escribir al revés una cadena de caracteres…………………….p.16
Ej14: palindroma……………………………………………………p.17
Tema 3:
Ej1: vector de 3 dimensiones……………………………………….p.18
Ej2: fecha…………………………………………………………p.19-21
Ej3: calculadora de nºracionales………………………………….p.22-24
Ej4: calculadora de nºimaginarios………………………………..p.25-26
Ej5: Persona: IMC, mayor de edad, generarDNI aleatorio, Boolean de
tipo de peso…………………………………………………..p.27-31
Ej6: Password: crear aleatoriamente en un array y decir si es fuerte…p.32-34
Ej10: salario trabajadores empresa…………………………………p.35-37
Ej11: cuentas bancarias…………………………………………….p.38-47
Ej12: fecha con excepciones……………………………………….p.48-50
Ej13: algoritmo de Newton-Raphson………………………………p.51-52
Tema 4:
Ej1: escribir caracteres y almacenar en fichero de texto………..p.53
Ej2: ej1 y mostrar contenido de un archivo…………………….p.54-55
Ej3: comprobar si dos archivos son iguales…………………….p.56-57
Ej4: contar número de palabras de un archivo
Tipo Test:
Tipo Test…………………………………………………………..p.63-65
Explica brevemente el método de búsqueda binaria ¿que prerequisites debe
cumplir?…………………………………………………………..p.66
Ejemplos Tipo:
Ej1: control de ventas de una tienda………………………………p.67-69
Ej2: figuras geométricas…………………………………………..p.70-74
Ej3: control de préstamos de una biblioteca………………………p.75-83
Ej4: empresa, empleados, jefe…………………………………….p.84-89
Ej5: lista de nº enteros…………………………………………….p.90-92
Ej6: representación de árbol binario y búsqueda enteros…………p.93-96
Ej7: MyArrayList que simule el arrayList de Java………………..p.97-100
Ej8: Ordenar array con el algoritmo “Bubble Sort”………………p.101
Ej9: juego de cartas……………………………………………….p.102-103
Ej10: socios de una sociedad……………………………………..p.104-108
Ej11: compra online………………………………………………p.109-125
Ejercicios Prácticos:
Ej1: transformar bucles…………………………………………..p.126
Ej2: UML sociedad………………………………………………p.127-128
Ej4: Preguntas clase test de código de figuras geométricas……..p.129-130
Ej5: ejercicio Metabolitos……………………………………….p.131-138
EJERCICIOS
TEMA 1
1. Escribir un programa que defina variables que representen el número de días de un
año, el número de horas que tiene un día, el número de minutos que tiene una hora y
el número de segundos que tiene un minuto. Emplear las variables que ocupen el
mínimo espacio de memoria posible. A continuación, calcular el número de segundos
que tiene un año y almacenar el valor del cálculo en otra variable. Realizar
preferiblemente mediante una función que reciba como parámetros el número de
años, meses y días y devuelva el número de segundos de los días, meses y años
introducidos.
package org.example;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
1
2. Escribir un programa que muestre por consola los mayores números enteros que se
pueden representar mediante un char, short e int.
package org.example;
package org.example;
2
public static int[] multiples(int begin, int end) {//creamos un afuncion para buscar los
multiplos y
// simplificar el codigo
//inicializamos un contador a 0
int count=0;
//contamos todos los multiplos que hay de 1 a 100
for(int i=begin; i <= end; i++){
if(i % 5 == 0){
count++;
}
}
//reservamos memoria para el numero justo de multiplos
int []multiple=new int[count];
//creamos una variable que nos va a permitir recorrer las posiciones del array
int j=0;
//recorremos el array para asignarle una posicion a cada multiplo
for (int i=begin; i <= end; i++) {
if (i % 5 == 0) {
multiple[j]=i;
j++;//avanzamos de una posicion en el array
}
}
//devolvemos a la funcion main el contenido de nuestro array
return multiple;
}
public static int suma(int []multiple){// funcion para realizar la suma de los multiplos
//inicializamos la suma a 0
int suma=0;
//realizamos la suma de cada uno de los vamores del array
for (int j : multiple) { //añadir multiple de 5 a la suma general
suma += j;
}
//devolver la suma total a la funcion
return suma;
}
}
3
4. Escribe un programa que calcule el mínimo y el máximo de una lista de números
enteros positivos introducidos por el usuario. La lista finalizará cuando se introduzca un
número negativo.
package org.example;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
4
5. Escribe un programa que visualice por pantalla la tabla de multiplicar de los 10
primeros números naturales. Utilizar una función que reciba un número N y devuelva
un array de arrays con las tablas de multiplicar de 0 a 9 de los N números
package org.example;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
5
6. Escribe un programa que muestre por pantalla la lista de los N primeros números
primos. Realiza una función que reciba N, devuelve un array conteniendo los N
primeros números primos y posteriormente imprima el array en el main.
package org.example;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
6
7. Escribe un programa que lea un número entero de teclado, lo guarde en una variable,
lo envíe a una función que lo descomponga en factores primos, y dicha función
devuelva un array que contenga los factores primos. Posteriormente imprima el array
en el main. ; por ejemplo 40 = 2 * 2 * 2 * 5.
package org.example;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
}
public static int numero(){
int N=-1;
try{
BufferedReader consola= new BufferedReader(new InputStreamReader(System.in));
System.out.println("Dame un numero positivo: ");
N = Integer.parseInt(consola.readLine());
} catch (IOException ioe) {
System.out.println(ioe);
}
return N;
}
public static int [] primos(int N){
int []factores= new int[N];
int j=0;
for(int i=2; i<=N; i++){
while (N%i==0){
factores[j]=i;
N/=i;
j++;
}
}
int []primo= new int[j];
for(int i=0; i<j; i++){
primo[i]=factores[i];
}
return primo;
} }
7
8. Empleando un array, escribir un programa que pida al usuario números enteros hasta
que se introduzca el número 0. A continuación, calcular la media, el mínimo y el
máximo de los datos introducidos. Utilice funciones independientes para: a) recibir N
números enteros por teclado hasta que el usuario introduzca un 0; b) Calcule la media
de los elementos de un array; c) calcule el mínimo de los elementos de un array; y d)
Calcule el máximo de los elementos de un array.
package org.example;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
8
suma += lista[i];
contador++;
}
}
media=suma/ contador;
return media;
}
public static int max(int []lista){
int max= Integer.MIN_VALUE;
for(int i=0; i< lista.length; i++){
if(lista[i]>max){
max=lista[i];
}
}
return max;
}
public static int min(int []lista){
int min= Integer.MAX_VALUE;
for(int i=0; i< lista.length; i++){
if(lista[i]<min && lista[i] !=0){
min=lista[i];
}
}
return min;
}
}
9
9. Escribir un programa que solicite al usuario dos vectores de N elementos y que
imprima su producto escalar. Utilice un array para representar el vector de N
elementos. Realice la entrada de usuario por teclado en una función que reciba las
dimensiones del vector a la que se invoca dos veces (una por vector) y otra función que
calcule el producto escalar recibiendo dos arrays que representan dos vectores.
package org.example;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
10
System.out.println("Introduce el numero de la posicion "+i);
vector[i]= Integer.parseInt(consola.readLine());
}
}catch (IOException e){
System.out.println(e.getMessage());
}
return vector;
}
public static int productoEscalar(int v1, int v2, int []V1, int []V2){
int producto=0;
int suma=0;
for(int i=0; i<v1; i++){
for(int j=0; j<v2; j++){
if(V1[i]!=0 && V2[j]!=0){
producto= V1[i]*V2[j];
suma+=producto;
}
}
}
return suma;
}
}
M
10. Escribir un programa que rellene una matriz cuadrada (las dimensiones de la matriz
serán un parámetro que se pida al usuario) con números aleatorios de tal modo que la
matriz sea simétrica. Imprimir la matriz por pantalla. Realice todo en una única función
a la que se llama desde el main.
package org.example;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Random;
12
11. Escribir un programa que multiplique dos matrices. Sus dimensiones y valores deben
de solicitarse al usuario por teclado y tras realizar la multiplicación debe visualizarse en
pantalla ambas matrices y el resultado de la multiplicación.
Cree una nueva función similar al ejercicio 9 pero que recibirá vectores de varias
dimensiones. Realice otra función multiplicar matrices que reciba dos arrays de dos
dimensiones que representan 2 vectores y devuelva otro array de dos dimensiones que
contenga su multiplicación. En caso de no ser compatibles las dimensiones la función
indicará que ha habido un error.
package org.example;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Random;
13
System.out.println(e.getMessage());
}
return matriz;
}
public static void imprimirMatriz(int [][]matriz){
System.out.println("Matriz creada:");
for (int i=0; i< matriz.length; i++){
for (int j=0; j< matriz.length; j++){
System.out.printf("%5d", matriz[i][j]);
}
System.out.println();
}
}
public static int [][]multiplicacion(int [][]matriz1, int [][]matriz2){
int dimension=0;
if (matriz1.length>matriz2.length){
dimension=matriz2.length;
}else{
dimension=matriz1.length;
}
int [][]matriz =new int [dimension][dimension];
for(int i=0; i< matriz1.length; i++){
for(int j=0; j< matriz2.length; j++){
matriz[i][j]= matriz1[i][j]*matriz2[i][j];
}
}
return matriz;
}
}
14
12. Escribe un programa que acepte una cadena de caracteres (que podrá contener
cualquier carácter a excepción del retorno de carro) y que diga cuántas vocales
contiene. Realice la entrada de teclado en una función (lectura de una string) y el
cálculo de vocales de una string en otra función independiente que reciba una string y
devuelva un entero.
package org.example;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Locale;
15
13. Escribe un programa que acepte una cadena de caracteres (que podrá contener
cualquier carácter a excepción del retorno de carro) y que la escriba al revés. Reutiliza
la función del ejercicio para la entrada de teclado y otra función que invierta la cadena.
package org.example;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
16
14. Escribe un programa que lee una cadena de caracteres de teclado e indique si es o no
palíndroma (se lee igual de izquierda a derecha que de derecha a izquierda, sin tener
en cuenta los espacios en blanco y las mayúsculas). Por ejemplo: "dábale arroz a la
zorra el abad". Reutilice la función del ejercicio 12 para la entrada de teclado y cree
otra función que dada una cadena de caracteres devuelva un boolean indicando si es o
no palíndroma
package org.example;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
17
EJERCICIOS
TEMA 3
1. Escribe un programa que cree una clase para representar un objeto punto en tres
dimensiones. Proporcionar un constructor que inicialice los valores del punto al origen
de coordenadas y otro que permita especificar las coordenadas del punto. Sobrescribe
su método toString() para que muestre información sobre los puntos. Usa la clase en
un programa donde crees objetos que representen los puntos (12, 13, 18) y (8, 14, 0) y
los muestres por consola.
package org.example;
public V3D() {
this.x = 0;
this.y = 0;
this.z = 0;
}
public V3D(double x, double y, double z) {
this.x = x;
this.y = y;
this.z = z;
}
public double getX() {
return x;
}
18
2. Crea una clase fecha que almacene el día, el mes y el año de una fecha. Proporciona
funciones miembro para acceder a estos atributos (getDia(), getMes() y getAño() y para
modificarlos (setDia(int dia), setMes(int mes) y setAño(int año)). Sobreescribe su
método toString(). Crea la fecha 20/10/2018. Muéstrala por pantalla. Después cambia
el año 2019. Muéstrala por pantalla.
package org.example;
19
package org.example;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public Fecha ( int dia, int mes, int anio) throws Exception {
try{
setDia(dia);
setMes(mes);
this.anio=anio;
}catch (IOException e){
System.out.println(e.getMessage());
}
}
@Override
public String toString(){
return dia+"/"+mes+"/"+anio;
}
public int getAnio() {
return anio;
}
public int getDia() {
return dia;
}
public int getMes() {
return mes;
}
public void setAnio(int anio) {
this.anio = anio;
}
public void setDia(int dia) throws Exception{
if(dia<1||dia>31){
Exception d= new Exception("El dia no es valido, error");
throw d;
}
this.dia = dia;
}
public void setMes(int mes) throws Exception{
if(mes<1||mes>12){
Exception d= new Exception("El mes no es valido, error");
throw d;
}
20
this.mes = mes;
}
public static void main(String[] args) {
BufferedReader teclado= new BufferedReader(new InputStreamReader(System.in));
int dia=0;
int mes=0;
int anio=0;
try{
System.out.println("Dame el dia: ");
dia=Integer.parseInt(teclado.readLine());
System.out.println("Dame el mes: ");
mes=Integer.parseInt(teclado.readLine());
System.out.println("Dame el anio: ");
anio=Integer.parseInt(teclado.readLine());
Fecha f1= new Fecha (dia, mes, anio);
System.out.println("Tu fecha es: "+f1);
}catch (IOException i){
System.out.println(i.getMessage());
} catch(Exception e){
System.out.println(e.getMessage());
}
21
3. Crear una clase que represente un número racional que permita, al menos, sumar,
multiplicar y simplificar números racionales. Proporcionar un constructor por defecto,
un constructor de copia (esto es, un Algoritmos y Estructuras de Datos Página 52 de 56
constructor al que se le pasa una instancia de la clase número racional y crea otro
número racional idéntico), y otro que permita indicar los valores del numerador y del
denominador. Usando esta clase, crea una calculadora que permita operar con
números racionales, seleccionando las operaciones de un menú.
package org.example;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
22
int denominador= f1.getDenominador()* f2.getDenominador();
int numerador= f1.getNumerador()* f2.getDenominador()- f2.getNumerador()*
f1.getDenominador();
return new NumeroRacional(numerador, denominador);
}
public static NumeroRacional multiplicacion(NumeroRacional f1, NumeroRacional f2){
int denominador= f1.getDenominador()* f2.getDenominador();
int numerador= f1.getNumerador()* f2.getNumerador();
return new NumeroRacional(numerador, denominador);
}
private static int mcd(int a, int b) {
if (b == 0) {
return a;
} else {
return mcd(b, a % b);
}
}
23
NumeroRacional f2= new NumeroRacional(numerador2,denominador2);
System.out.println("Tu segundo nº racional: "+f2);
do{
menu();
opcion=Integer.parseInt(teclado.readLine());
switch (opcion){
case 1:
NumeroRacional suma= suma(f1,f2);
System.out.println("La suma de tus racionales es: "+ suma);
NumeroRacional simplicacion= simplificar(suma); //Como aqui declaramos
simplicacion
// como un numero racional se aplica al resto
System.out.println("Tu funcion simplificada: "+simplicacion);
break;
case 2:
NumeroRacional resta= resta(f1, f2);
System.out.println("La resta de tus racionales es: "+ resta);
simplicacion = simplificar(resta);
System.out.println("Tu funcion simplificada: "+simplicacion);
break;
case 3:
NumeroRacional multiplicacion= multiplicacion(f1, f2);
System.out.println("La multiplicacion de tus racionales es: "+ multiplicacion);
simplicacion= simplificar(multiplicacion);
System.out.println("Tu funcion simplificada: "+simplicacion);
break;
case 4:
System.out.println("Que fracion quieres simplificar? ");
System.out.println("Fraccion 1: "+f1);
System.out.println("Fraccion 2: "+f2);
sub_opcion=Integer.parseInt(teclado.readLine());
if(sub_opcion==1){
simplicacion= simplificar(f1);
System.out.println("Tu funcion simplificada: "+simplicacion);
}else if(sub_opcion==2){
simplicacion= simplificar(f2);
System.out.println("Tu funcion simplificada: "+simplicacion);
}else{
System.out.println("Opcion no valida.");
}
break;
default:
System.out.println("Opcion no valida");
}
}while (opcion>0 && opcion<4) }catch (IOException i) Sout (i.getMessage()); } } }
24
4. Repetir el ejercicio anterior, pero creando una clase que represente a un número
complejo.
package org.example;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
25
int imaginario= f1.getReal()* f2.getImaginario()+f1.getImaginario()*f2.getReal();
return new NumeroComplejo(real, imaginario);
}
public static void menu(){
System.out.println("1. Suma");
System.out.println("2. Resta");
System.out.println("3. Multiplicacion");
System.out.println("Opcion: ");
}
public static void main(String[] args) {
BufferedReader teclado= new BufferedReader(new InputStreamReader(System.in));
int real1=0;
int imaginario1=0;
int real2=0;
int imaginario2=0;
int opcion=0;
try{
System.out.println("Dame un numerador: ");
real1=Integer.parseInt(teclado.readLine());
System.out.println("Dame un denominador: ");
imaginario1=Integer.parseInt(teclado.readLine());
NumeroComplejo f1= new NumeroComplejo(real1,real2);
System.out.println("Tu primer nº racional: "+f1);
System.out.println("Dame un numerador: ");
real2=Integer.parseInt(teclado.readLine());
System.out.println("Dame un denominador: ");
imaginario2=Integer.parseInt(teclado.readLine());
NumeroComplejo f2= new NumeroComplejo(real2,imaginario2);
System.out.println("Tu segundo nº racional: "+f2);
do{
menu();
opcion=Integer.parseInt(teclado.readLine());
switch (opcion){
case 1:
NumeroComplejo suma= suma(f1,f2);
System.out.println("La suma de tus complejos es: "+ suma);
break;
case 2:
NumeroComplejo resta= resta(f1, f2);
System.out.println("La resta de tus complejos es: "+ resta);
break;
case 3:
NumeroComplejo multiplicacion= multiplicacion(f1, f2);
System.out.println("La multiplicacion de tus complejos es: "+ multiplicacion);
break;
default:
System.out.println("Opcion no valida");
}
26
}while (opcion>0 && opcion<3);
5. (30 minutos) Haz una clase llamada Persona con atributos: nombre, edad, DNI, sexo (usa una
enumeración), peso y altura. Crea métodos para acceder y modificar todos los atributos. Por
defecto, todos los atributos menos el DNI tendrán valores por defecto según su tipo (0
números, cadena vacía para String, etc.).
Sexo será mujer por defecto. La clase deberá tener los siguientes constructores constructores:
• Un constructor por defecto.
• generaDNI(): genera un número aleatorio de 8 cifras que será el DNI de la persona. Este
método no será visible desde el exterior. Este método deberá invocarse desde cualquier
constructor para generar el DNI.
• Crea 3 objetos de la clase anterior, el primer objeto obtendrá las anteriores variables pedidas
por teclado, el segundo objeto obtendrá todos los anteriores menos el peso y la altura y el
último por defecto, para este último utiliza los métodos set para darle a los atributos un valor.
• Para cada objeto, se deberá comprobar si está en su peso ideal, tiene sobrepeso o por debajo
de su peso ideal con un mensaje.
package org.example;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
27
import java.util.Random;
}
public Persona(){
this.nombre= " ";
this.sexo= Sexo.FEMALE;
this.edad=0;
this.dni=" ";
this.peso=0;
this.altura=0;
}
public Persona(String nombre, int edad, Sexo sexo){
this.nombre= nombre;
this.sexo= sexo;
this.edad=edad;
this.dni=" ";
this.peso=0;
this.altura=0;
}
28
}
this.altura = altura;
}
29
public void setNombre(String nombre) {
this.nombre = nombre;
}
30
dni=generaDNI();
double imc= calcularIMC(peso, altura);
System.out.println("Su imc es: "+imc);
int valorC= valorPesoCorporal(imc);
if(valorC== 1){
System.out.println("La persona tiene sobrepeso.");
}else if(valorC== -1){
System.out.println("La persona esta por debajo de su peso ideal");
}else{
System.out.println("La persona esta en su peso ideal.");
}
boolean mayor= esMayorDeEdad(edad);
if(mayor==true){
System.out.println("La persona es mayo de edad");
}else{
System.out.println("La persona es menor de edad");
}
Persona persona1= new Persona(nombre, edad, dni, peso, altura, sexo);
System.out.println("La persona con toda su informacion: "+persona1);
Persona persona2= new Persona(nombre, edad, sexo);
System.out.println("La persona con parte de su informacion: "+persona2);
Persona persona3= new Persona();
System.out.println("La persona con el constructor por defecto: "+ persona3);
}catch (IOException e){
System.out.println(e.getMessage());
}catch (Exception i){
System.out.println(i.getMessage());
}
}
}
3
6. Haz una clase llamada Password que tenga los atributos longitud y contraseña . Por defecto,
la longitud será de 8. Los constructores serán los siguiente:
• Un constructor con la longitud que nosotros le pasemos. Generará una contraseña aleatoria
con esa longitud. Los métodos de esta clase serán:
• esFuerte(): devuelve un booleano si es fuerte o no, para que sea fuerte debe tener más de 2
mayúsculas, más de 1 minúscula y más de 5 números.
• Cree un bucle que cree un objeto para cada posición del array. Indica por teclado la longitud
de cada password.
• Crea otro array de booleanos donde se almacene si el password del array de Password es o
no fuerte (usa el bucle anterior).
• Al final, muestra la contraseña y si es o no fuerte (usa el bucle anterior). Usa este simple
formato: contraseña1 valor_booleano1, contraseña2 valor_bololeano2
package org.example;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Random;
32
public void setLongitud(int longitud) throws Exception {
if(longitud>8){
Exception t= new Exception("Has sobrepasado la longitud");
throw t;
}
if(longitud<0){
Exception e= new Exception("La longitud es muy pequenia");
throw e;
}
this.longitud = longitud;
}
public String generaContra(){
StringBuilder constructor = new StringBuilder(this.longitud);
Random random = new Random();
String may = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
String min = "abcdefghijklmnopqrstuvwxyz";
String num = "0123456789";
String symbols = "!@#$%^&*()_-+={[}]|\\:;\"'<,>.?/";
String Caracteres = may + min + num + symbols;
for (int i = 0; i < this.longitud; i++) {
int index = random.nextInt(Caracteres.length());
constructor.append(Caracteres.charAt(index));
}
return constructor.toString();
}
public boolean esFuerte(){
int numMayusculas = 0;
int numMinusculas = 0;
int numNumeros = 0;
for (int i = 0; i < contrasenia.length(); i++) {
char c = contrasenia.charAt(i);
if (Character.isUpperCase(c)) {
numMayusculas++;
} else if (Character.isLowerCase(c)) {
numMinusculas++;
} else if (Character.isDigit(c)) {
numNumeros++;
}
}
return numMayusculas > 2 && numMinusculas > 1 && numNumeros > 5;
}
33
public String getContrasenia() {
return contrasenia;
}
}
}
34
10. En una empresa todos los trabajadores tienen un sueldo base de 1000 €. Los jefes tienen
un suplemento de 500 € por cada año que hayan sido jefe de la empresa, y los viajantes
además del sueldo base cobran 300 € por viaje realizado. Crear una clase empleado de la cual
deriven las clases jefe y viajante. Crear una plantilla de una empresa con dos jefes, cinco
viajantes y 15 empleados, e imprimir por consola sus respectivos salarios. Para generar el
número de viajes de los viajantes y la antigüedad de los jefes puedes generar números
aleatorios entre 0 y 10. Emplea el polimorfismo de herencia.
@Override
public String toString() {
return "Sueldo empleado corriente: "+dinero_trabajador;
}
}
35
public class Viajantes extends Empleado {
public int viajeros;
public Viajantes(){
int viajes=generaViajes();
this.viajeros=viajes*300;
}
36
public void setJefes(Jefes[] jefes) {
this.jefes = jefes;
}
37
11. Crea la clase cuenta bancaria, que deberá tener como atributos un nombre de titular, una
fecha de apertura, un número de cuenta y un saldo (puedes emplear un número real. La
cuenta deberá tener un método para retirar dinero, otro para ingresar dinero y otro para
transferir dinero a otra cuenta. De una cuenta no se podrá retirar nunca dinero (ni transferir) si
la cantidad de dinero a retirar o transferir es mayor que el saldo.
- Crea una cuenta a plazo fijo, en la cual cuando se retira dinero de algún modo antes de una
fecha de vencimiento (que será otro atributo de esta clase) además del dinero a retirar se
penaliza con un 5% adicional.
- Crea además una cuenta Vip, que tendrá un atributo adicional que es el saldo negativo
máximo que puede tener. En las cuentas Vip uno podrá tener saldo negativo siempre que no
supere este valor.
- A continuación, construye un main que permita crear los tres tipos de cuentas, y transferir
dinero de unas a otras, ingresar dinero y retirar dinero. Almacena las cuentas en un array.
Emplea polimorfismo de herencia.
package org.example.cuentaBancaria;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.time.LocalDate;
38
numeroCuenta=Double.parseDouble(teclado.readLine());
System.out.println("Saldo: ");
saldo=Double.parseDouble(teclado.readLine());
cuentaPlazo1= new CuentaPlazo(nombre, numeroCuenta, saldo);
34
cantidad=Double.parseDouble(teclado.readLine());
cuentaBancaria1.ingresar(cantidad);
break;
case 2:
System.out.println("¿Cuanto dinero quieres ingresar? ");
cantidad=Double.parseDouble(teclado.readLine());
cuentaPlazo1.ingresar(cantidad);
break;
case 3:
System.out.println("¿Cuanto dinero quieres ingresar? ");
cantidad=Double.parseDouble(teclado.readLine());
cuentaVip1.ingresar(cantidad);
break;
}
break;
case 3:
System.out.println("De que cuenta a que cuenta quieres transferir dinero? ");
System.out.println("1. Cuenta Bancaria--> Cuenta a Plazos");
System.out.println("2. Cuenta Bancaria--> Cuenta a vip");
System.out.println("3. Cuenta a Plazos--> Cuenta Bancaria");
System.out.println("4. Cuenta a Plazos--> Cuenta a Vip");
System.out.println("5. Cuenta vip--> Cuenta Bamcaria");
System.out.println("6. Cuenta vip--> Cuenta a Plazos");
opcion1=Integer.parseInt(teclado.readLine());
switch (opcion1){
case 1:
System.out.println("¿Cuanto dinero quieres ingresar? ");
cantidad=Double.parseDouble(teclado.readLine());
cuentaBancaria1.transferir1(cuentaPlazo1, cantidad);
break;
case 2:
System.out.println("¿Cuanto dinero quieres ingresar? ");
cantidad=Double.parseDouble(teclado.readLine());
cuentaBancaria1.transferir2(cuentaVip1, cantidad);
break;
case 3:
System.out.println("¿Cuanto dinero quieres ingresar? ");
cantidad=Double.parseDouble(teclado.readLine());
cuentaPlazo1.transferir1(cuentaBancaria1, cantidad);
break;
case 4:
System.out.println("¿Cuanto dinero quieres ingresar? ");
cantidad=Double.parseDouble(teclado.readLine());
cuentaPlazo1.transferir2(cuentaVip1, cantidad);
break;
case 5:
System.out.println("¿Cuanto dinero quieres ingresar? ");
cantidad=Double.parseDouble(teclado.readLine());
40
cuentaVip1.transferir1(cuentaBancaria1, cantidad);
break;
case 6:
System.out.println("¿Cuanto dinero quieres ingresar? ");
cantidad=Double.parseDouble(teclado.readLine());
cuentaVip1.transferir2(cuentaPlazo1, cantidad);
break;
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
41
public void setNombreTitular(String nombreTitular) {
this.nombreTitular = nombreTitular;
}
42
if (cantidad <= this.saldo) {
retirar(cantidad);
cuentaDestino.ingresar(cantidad);
} else {
System.out.println("No se ha podido transferir dinero");
}
}
@Override
public String toString() {
return "Nombre: " + nombreTitular + "\nFecha: " + date + "\nNumero cuenta: " +
numeroCuenta + "\nSaldo: " + saldo;
}
}
43
try {
System.out.println("Fecha de vencimiento:");
System.out.println("Anio: ");
anio = Integer.parseInt(teclado.readLine());
System.out.println("Mes: ");
mes = Integer.parseInt(teclado.readLine());
System.out.println("Dia: ");
dia = Integer.parseInt(teclado.readLine());
vencimiento = LocalDate.of(anio, mes, dia);
System.out.println(vencimiento);
this.vencimiento = vencimiento;
}catch (IOException e){
System.out.println(e.getMessage());
}
}
public void setNombreTitular(String nombreTitular) {
this.nombreTitular = nombreTitular;
}
public void setNumeroCuenta(double numeroCuenta) {
this.numeroCuenta = numeroCuenta;
}
public void setSaldo(double saldo) {
this.saldo = saldo;
}
public double retirar(double cantidad) {
if (saldo >= cantidad) {
double penalizacion= cantidad*1.05;
double nuevoSaldo = this.saldo - penalizacion;
System.out.println("Se ha podido retirar " + cantidad + "euros. " + "\nSaldo actual: " +
nuevoSaldo);
return nuevoSaldo;
} else {
System.out.println("No se ha podido retirar dinero. \nTu saldo sigue siendo de " +
this.saldo + "euros.");
return this.saldo;
}
}
44
} else {
System.out.println("No se ha podido transferir dinero");
}
}
public void transferir1(CuentaBancaria cuentaDestino, double cantidad) {
if (cantidad <= this.saldo) {
retirar(cantidad);
cuentaDestino.ingresar(cantidad);
} else {
System.out.println("No se ha podido transferir dinero");
}
}
public void transferir2(CuentaVip cuentaDestino, double cantidad) {
if (cantidad <= this.saldo) {
retirar(cantidad);
cuentaDestino.ingresar(cantidad);
} else {
System.out.println("No se ha podido transferir dinero");
}
}
@Override
public String toString() {
return "Nombre: " + nombreTitular + "\nFecha: " + date + "\nNumero cuenta: " +
numeroCuenta + "\nSaldo: " + saldo;
}
}
45
return saldo;
}
46
@Override
public String toString() {
return "Nombre: " + nombreTitular + "\nFecha: " + date + "\nNumero cuenta: " +
numeroCuenta + "\nSaldo: " + saldo;
}
}
47
12. Crea una clase fecha que almacene el día, el mes y el año de una fecha. Proporciona
funciones miembro para acceder a estos atributos (getDia(), getMes() y getAño() y para
modificarlos (setDia(int dia), setMes(int mes) y setAño(int año)).
Sobreescribe su método toString().
La clase debe asegurarse de que los valores introducidos para sus miembros, tanto a través de
los constructores como de los métodos modificadores, se corresponden con una fecha válida
(no es necesario tener en cuenta años bisiestos).
Para ello lanzará una excepción en caso de que los datos no sean válidos. Crea la fecha
31/02/2015 y verifica que se lanza la excepción correspondiente. Verifica que esto también
sucede al invocar el método setDia (35).
package org.example;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
48
dia = anio % 4 == 0 ? 29 : 28;// "?" representa el if y ":" el else
// es decir si es divisible por 4 entonces el mes tiene 29 dias y si no el mes tiene 28
System.out.println("el mes es bisiesto");
break;
case 4:
case 6:
case 9:
case 11:
dia = 30;
break;
default:
dia = 31;
}
return dia;
}
public void setAnio(int anio) throws Exception{
if(anio<1){
Exception t= new Exception("Anio INCORRECTO");
throw t;
}
this.anio = anio;
}
@Override
public String toString() {
return dia+"/"+mes+"/"+anio;
}
49
try {
do{
System.out.println("Pulse 1 para introducir otra fecha y 0 para salir: ");
opcion=Integer.parseInt(teclado.readLine());
System.out.println("Dia: ");
dia=Integer.parseInt(teclado.readLine());
System.out.println("Mes: ");
mes=Integer.parseInt(teclado.readLine());
System.out.println("Anio: ");
anio=Integer.parseInt(teclado.readLine());
fecha[contador]= new Fecha(dia,mes,anio);
contador++;
}while (opcion!=0);
}catch (IOException e){
System.out.println(e.getMessage());
}
}
}
so
13. Escribir un resolvedor que busque raíces de una función empleando el algoritmo de
Newton-Raphson para encontrar una raíz de una función concreta.
Este método parte de una estimación inicial de la raíz, x0, y va calculando aproximaciones
sucesivas al valor de la misma utilizando la fórmula: xi+1=xi-f(xi)/f'(xi)
Al ser un método iterativo, es necesario tener un criterio para que termine. Puede establecerse
como criterio de terminación que la diferencia entre f(x) y 0 sea menor que un valor e
pequeño.
Además, por seguridad, se debe establecer un número máximo de iteraciones para que el
algoritmo termine, aunque no converja a una solución (de lo contrario, al ejecutarlo en el
ordenador éste podría quedarse bloqueado).
package org.example;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
double x = x0;
int iter = 0;
if (Math.abs(fx) < e) {
System.out.println("La raíz de la función es: " + x);
return;
}
x = x - fx/fpx;
iter++;
}
51
} catch (IOException ex) {
System.err.println(ex.getMessage());
}
}
7. Usando las clases del código de ejemplo de los marcianos, construye una guerra donde
combatan 5 naves de los marcianos y 10 naves de los terrícolas.
8. Usando las clases del código de ejemplo del resolvedor de raíces, añade una nueva función
que permita representar un polinomio de grado n. Crea esta función en tu propio paquete.
Utilizando el resolvedor sin modificar ninguna línea de código, busca raíces de tu polinomio.
9. Crea un nuevo método en la clase resolvedor tal que uno pueda especificar una función, y
no sea necesario indicar el intervalo inicial para buscar la raíz. El propio método va a tratar de
buscar un intervalo adecuado. Trata de idear una estrategia adecuada para encontrar ese
intervalo.
32
EJERCICIOS
TEMA 4
1. Escribe un programa que pida sucesivamente líneas de caracteres al usuario hasta que
este introduzca una "x". Las líneas de caracteres las irá almacenando en un archivo de
texto.
package org.example;
import java.io.BufferedReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
33
2. Modificar el programa anterior añadiendo una opción que permita realizar un listado
del archivo de texto. El programa constará de un primer menú donde el usuario indica
si desea listar el contenido del archivo que está en el disco duro o introducir más líneas
de texto. Si realiza el listado, tras mostrar las líneas por pantalla se vuelve al menú
principal. Si está introduciendo líneas de texto y pulsa "x" se vuelve al menú principal.
package org.example;
import java.io.*;
54
break;
case 3:
exit=true;
break;
default:
System.out.println("Opción no valida");
break;
}
}catch(IOException e){
System.out.println("ERROR: " + e.getMessage());
}
}while (opcion != 0) ;
}
55
3. Escribe un programa que pida el nombre de dos archivos al usuario y compruebe si
ambos archivos son o no iguales.
package org.example;
import java.io.*;
56
return byte1 == byte2;
}catch (IOException e){
System.out.println("Error al comparar archivos:
"+e.getMessage());
return false;
}
}
}
57
4. Escribe un programa que cuente el número de palabras que contiene un archivo de
texto; el nombre del archivo de texto será introducido por el usuario.
package org.example;
import java.io.*;
58
5. Escribe un programa que reciba como argumentos un archivo de texto y una palabra a
buscar en ese archivo. El programa debe contar el número de veces que aparece la
palabra en el archivo.
package org.example;
import java.io.*;
59
6. Crea un programa que permita guardar y cargar del disco duro contactos de una
agenda telefónica. Cada contacto, que deberá representarse mediante una clase,
constará del nombre de una persona, su e-mail y su número de teléfono. El programa
al arrancar, a través de un menú de consola, permitirá al usuario introducir más
contactos, listar los contactos existentes, o salir del programa.
package org.example.Contacto;
package org.example.Contacto;
import java.io.*;
60
public static void main(String[] args) {
int opcion=0;
String nombre;
String email;
int numeroTel;
Contacto contacto;
BufferedReader teclado= new BufferedReader(new
InputStreamReader(System.in));
boolean exit=false;
try {
do{
menu();
opcion=Integer.parseInt(teclado.readLine());
switch (opcion){
case 1:
FileWriter agenda = new
FileWriter("archivo.txt", true);
System.out.println("Dame el nombre del
contacto: ");
nombre= teclado.readLine();
System.out.println("Dame el email del
contacto: ");
email= teclado.readLine();
System.out.println("Dame el telefono del
contacto: ");
numeroTel=Integer.parseInt(teclado.readLine());
contacto= new Contacto(nombre, email,
numeroTel);
agenda.write(contacto.toString()+"\n");
agenda.close();
break;
case 2:
System.out.println("Contenido de la agenda:
");
FileReader fileReader= new
FileReader("archivo.txt");
BufferedReader bufferedReader= new
BufferedReader(fileReader);
String file="";
while ((file= bufferedReader.readLine())
!=null){
System.out.println(file);
}
bufferedReader.close();
fileReader.close();
break;
case 3:
exit=true;
break;
6
default:
System.out.println("Opción no valida");
break;
}
}while (opcion!=0);
}catch (IOException e){
System.out.println(e.getMessage());
}
}
public static void menu(){
System.out.println("1. Introducir contacto en la angenda.\n");
System.out.println("2. Listar contactos.\n");
System.out.println("3. Salir\n");
System.out.println("Opcion: ");
}
}
62
Tipo Test
1. Cuál de las siguientes afirmaciones es falsa:
(a) Un objeto es una instancia concreta de una clase abstracta
(b) Un objeto es una instancia concreta de una clase
5. Si tenemos una variable local, declarada dentro del ámbito de un bloque try podemos
afirmar que:
(a) La variable no es visible dentro de los bloques catch y finally.
(b) La variable es visible dentro del bloque finally pero no dentro del bloque catch.
6. El hecho de que un objeto pueda utilizarse en cualquier método que reciba como
parámetro a cualquier instancia de sus clases padre, se denomina:
(a) Herencia
(b)Polimorfismo
7. Gracias al mecanismo de herencia, una clase hija tiene acceso a públicos, protegidos y
amistosos definidos en su clase padre:
(a) Verdadero.
(b) Falso
8. Al hecho de que, dentro de una misma clase existan dos métodos con el mismo
nombre pero diferente numero/tipo de argumentos, se le denomina:
(a) Sobre escritura de métodos
(b) Sobrecarga de métodos
9. Al utilizar un array en Java podemos acceder a la longitud del mismo gracias a que el
atributo que define dicha longitud tiene una visibilidad:
(a) public
(b) protected
63
11. Cuando una subclase especifica un método que tiene: el mismo nombre, el mismo
numero y el mismo tipo de argumentos que un método declarado en alguna de sus
superclases, esa clase está:
(a) Sobreescribiendo ese método
(b) Sobrecargando ese método
15. Imagine que la clase C hereda de la clase B. Y la clase B hereda de la clase A. Cuando
se cree un objeto de la clase C, ¿Cuál será la secuencia en que se ejecutarán los
constructores?
(a) Primero el constructor C, luego el constructor B y, finalmente, el constructor A.
(b) Primero el constructor A, luego el constructor B y, finalmente, el constructor C.
17. Una clase de Java puede estar formada por clases, métodos y funciones.
(a) Verdadero
(b) Falso.
19. Las variables y objetos en Java deben liberarse de forma explícita cuando no se vayan
a utilizar más:
(a) Verdadero
(b) Falso.
64
21. Los elementos que definen a un objeto son:
a) El tipo de visibilidad que tiene asignado: privado o público.
b) Los atributos que representan su estado y los métodos que representan su comportamiento.
23. Imagine que la clase C hereda de la clase B. Y la clase B hereda de la clase A. Cuando
se cree un objeto de la clase C, ¿cuál será la secuencia en que se ejecutarán los
constructores?
a) Primero el constructor de C, luego constructor de B y, finalmente, el constructor de A
b) Primero el constructor de A, luego constructor de B y, finalmente, el constructor de C
65
El método de búsqueda binaria es un algoritmo para buscar un elemento específico en una lista
ordenada. Este algoritmo comienza dividiendo la lista en dos mitades y comparando el valor
medio con el valor que se está buscando. Si el valor medio es menor que el valor buscado, se
descarta la mitad inferior de la lista, y se realiza la misma operación en la mitad superior de la
lista. Si el valor medio es mayor que el valor buscado, se descarta la mitad superior de la lista y se
realiza la misma operación en la mitad inferior. Este proceso se repite hasta que se encuentra el
valor buscado o se descubre que no está en la lista.
Para que el método de búsqueda binaria funcione correctamente, la lista debe estar ordenada
previamente en orden ascendente o descendente. Además, el método de búsqueda binaria se
utiliza típicamente en listas de tamaño significativo, ya que si la lista es muy pequeña, el costo de
la búsqueda binaria puede ser mayor que el de otros métodos de búsqueda.
66
Ejemplos Tipo
1. Supongamos que necesitamos desarrollar un programa en Java para llevar un control
de ventas de una tienda. Cada venta está compuesta por un código de producto, una
cantidad vendida y un precio unitario. Se pide implementar una clase Venta con los
siguientes métodos:
• Constructor: que recibe como parámetros el código de producto, la cantidad vendida
y el precio unitario.
• Métodos getters y setters para los atributos de la venta.
• Método calcularTotal: que devuelve el total de la venta (cantidad vendida x precio
unitario).
• Método toString: que devuelve una cadena con los datos de la venta en el formato
"Producto: [código], cantidad: [cantidad], precio unitario: [precio], total: [total]".
Además, se pide implementar una clase Tienda que contenga un arreglo de ventas y que
tenga los siguientes métodos:
67
}
@Override
public String toString() {
return "Producto: " + codigoProducto + ", cantidad: " +
cantidadVendida + ", precio unitario: " +
precioUnitario + ", total: " + calcularTotal();
}
}
package org.example.tienda;
68
ventas[numVentas] = venta;
numVentas++;
}
@Override
public String toString() {
String resultado = "";
for (int i = 0; i < numVentas; i++) {
resultado += "Venta " + (i+1) + ": " + ventas[i].toString()
+ "\n";
}
return resultado;
}
tienda.agregarVenta(1, 5, 10.5);
tienda.agregarVenta(2, 3, 7.75);
tienda.agregarVenta(3, 2, 20.0);
69
2. Supongamos que tenemos un conjunto de figuras geométricas (círculos, cuadrados y
triángulos) representadas por objetos de sus respectivas clases: Circulo, Cuadrado y
Triangulo. Se pide implementar una clase ColeccionFiguras que contenga un arreglo
de figuras y que tenga los siguientes métodos:
• Constructor: que recibe como parámetro el tamaño del arreglo.
• Método agregarFigura: que recibe como parámetro una figura y la agrega al arreglo.
• Método areaTotal: que devuelve el área total de todas las figuras en la colección.
• Método promedioPerimetro: que devuelve el promedio de los perímetros de todas
las figuras en la colección.
• Método toString: que devuelve una cadena con los datos de todas las figuras en la
colección en el formato "Figura [i]: [tipo], área: [área], perímetro: [perímetro]".
package org.example.geometria;
70
public Circulo(double radio) {
this.radio = radio;
calcularArea();
calcularPerimetro();
}
7
@Override
public void calcularPerimetro() {
setPerimetro(4 * lado);
}
}
72
public void setLado3(double lado3) {
this.lado3 = lado3;
calcularArea();
calcularPerimetro();
}
73
areaTotal += figuras[i].calcularArea();
}
return areaTotal;
}
-4
3. Supongamos que se desea desarrollar una aplicación para una biblioteca que
permita llevar el control de los préstamos de libros. Se pide implementar las
siguientes clases:
• Una clase Libro que contenga los siguientes atributos: Título del libro (String), Autor
del libro (String), ISBN del libro (String), Cantidad de ejemplares del libro (int).
• Una clase Usuario que contenga los siguientes atributos: Nombre del usuario (String)
y DNI del usuario (String).
• Una clase Prestamo que contenga los siguientes atributos: Libro prestado (objeto de
la clase Libro), Usuario que ha solicitado el préstamo (objeto de la clase Usuario),
Fecha de inicio del préstamo (objeto de la clase LocalDate), Fecha de fin del
préstamo (objeto de la clase LocalDate).
• Una clase Biblioteca que contenga los siguientes métodos:
o Método agregarLibro: que recibe como parámetro un objeto de la clase Libro
y lo agrega a una lista de libros disponibles.
o Método agregarUsuario: que recibe como parámetro un objeto de la clase
Usuario y lo agrega a una lista de usuarios registrados en la biblioteca.
o Método prestarLibro: que recibe como parámetro el ISBN de un libro y el DNI
de un usuario y, si el libro está disponible y el usuario está registrado en la
biblioteca, crea un objeto de la clase Prestamo y lo agrega a una lista de
préstamos realizados.
o Método devolverLibro: que recibe como parámetro el ISBN de un libro y, si
existe un préstamo asociado al libro y aún no ha vencido la fecha de
devolución, actualiza la cantidad de ejemplares disponibles y elimina el
préstamo de la lista de préstamos realizados.
o Método listarLibrosDisponibles: que devuelve una cadena con el título, autor,
ISBN y cantidad de ejemplares disponibles de todos los libros disponibles en
la biblioteca.
o Método listarUsuariosRegistrados: que devuelve una cadena con el nombre y
DNI de todos los usuarios registrados en la biblioteca.
o Método listarPrestamos: que devuelve una cadena con el título, autor, ISBN,
nombre y DNI de los usuarios y fechas de inicio y fin de todos los préstamos
realizados en la biblioteca.
package org.example.biblioteca;
import java.time.LocalDate;
75
}
76
public Prestamo(Libro libroPrestado, Usuario usuario, LocalDate
fechaInicio, LocalDate fechaFin) {
this.libroPrestado = libroPrestado;
this.usuario = usuario;
this.fechaInicio = fechaInicio;
this.fechaFin = fechaFin;
}
78
}
package org.example.biblioteca;
79
}
package org.example.biblioteca;
import java.time.LocalDate;
80
// Buscamos el libro por su ISBN en la lista de libros
disponibles
for (int i = 0; i < numLibrosDisponibles; i++) {
if (librosDisponibles[i].getIsbn().equals(isbn)) {
libroPrestado = librosDisponibles[i];
break;
}
}
if (numPrestamosRealizados <
prestamosRealizados.length) {
prestamosRealizados[numPrestamosRealizados] =
prestamo;
numPrestamosRealizados++;
} else {
System.out.println("No se pueden realizar más
préstamos, la biblioteca ha alcanzado el límite.");
return;
}
libroPrestado.setCantidadEjemplares(libroPrestado.getCantidadEjempla
res() - 1);
System.out.println("El libro " +
libroPrestado.getTitulo() + " ha sido prestado a " +
usuarioSolicitante.getNombre() + ".");
} else {
System.out.println("El libro " +
8
libroPrestado.getTitulo() + " ha sido prestado a " +
usuarioSolicitante.getNombre() + ".");
} else {
System.out.println("El libro " +
libroPrestado.getTitulo() + " no está disponible en este momento.");
}
} else {
System.out.println("El libro o el usuario no están
registrados.");
}
}
public void devolverLibro(String isbn) {
Prestamo prestamoEncontrado = null;
for (Prestamo prestamo : prestamosRealizados) {
if (prestamo.getLibroPrestado().getIsbn().equals(isbn)
&& prestamo.getFechaFin().isAfter(LocalDate.now())) {
prestamoEncontrado = prestamo;
prestamo.getLibroPrestado().setCantidadEjemplares(prestamo.getLibroP
restado().getCantidadEjemplares() + 1);
break;
}
}
if (prestamoEncontrado != null) {
prestamosRealizados.remove(prestamoEncontrado);
System.out.println("El libro " +
prestamoEncontrado.getLibroPrestado().getTitulo() + " ha sido
devuelto correctamente.");
} else {
System.out.println("No existe un préstamo activo para el
libro con ISBN " + isbn + ".");
}
}
82
public String listarUsuariosRegistrados() {
StringBuilder sb = new StringBuilder();
for (Usuario usuario : usuariosRegistrados) {
sb.append("Nombre: " + usuario.getNombre() + ", DNI: " +
usuario.getDni() + "\n");
}
return sb.toString();
}
83
4. Se desea implementar una clase en Java que represente una empresa que tiene
empleados. La empresa tiene un jefe, que es un empleado con una serie de
privilegios, como por ejemplo, poder contratar y despedir empleados, y un conjunto
de empleados regulares. Cada empleado tiene un nombre, un número de
identificación y un salario. Además, los empleados regulares tienen un número de
horas trabajadas.
• La clase Empresa deberá tener los siguientes métodos:
o Contratar un empleado regular, el cual será añadido al conjunto de
empleados.
o Despedir un empleado regular, el cual será eliminado del conjunto de
empleados.
o Aumentar el salario de un empleado, dada su identificación.
o Añadir horas trabajadas a un empleado regular, dada su identificación.
o Obtener la cantidad total de salarios que paga la empresa.
o Obtener el empleado con el salario más alto.
• La clase Empleado debe tener los siguientes métodos:
o Devolver el nombre del empleado.
o Devolver la identificación del empleado.
o Devolver el salario del empleado.
• La clase Jefe debe heredar de la clase Empleado e incluir los siguientes métodos:
o Contratar un empleado regular.
o Despedir un empleado regular.
o Aumentar el salario de un empleado regular.
o Obtener la cantidad total de salarios que paga la empresa.
o Obtener el empleado con el salario más alto.
package org.example.empresa;
84
}
package org.example.empresa;
85
private int cantidadEmpleados;
86
return total;
}
public Empresa() {
empleadosRegulares = new Empleado[100]; // se asume un
máximo de 100 empleados regulares
cantidadEmpleadosRegulares = 0;
}
87
break;
}
}
}
88
private Empleado buscarEmpleado(int identificacion) {
if (jefe != null && jefe.getIdentificacion() ==
identificacion) {
return jefe;
}
for (int i = 0; i < cantidadEmpleadosRegulares; i++) {
if (empleadosRegulares[i].getIdentificacion() ==
identificacion) {
return empleadosRegulares[i];
}
}
return null;
}
}
89
5. Se desea implementar una clase en Java que represente una lista enlazada de
números enteros. La clase debe tener los siguientes métodos:
• add(int x): Añade un elemento al final de la lista.
• insert(int x, int i): Inserta un elemento en la posición i de la lista.
• remove(int i): Elimina el elemento en la posición i de la lista.
• get(int i): Devuelve el elemento en la posición i de la lista.
• size(): Devuelve el número de elementos en la lista.
• clear(): Elimina todos los elementos de la lista.
• toString(): Devuelve una cadena de caracteres que representa la lista, en el
formato [elemento1, elemento2, ..., elementoN].
La clase deberá tener un constructor por defecto que cree una lista vacía.
package org.example.LinkedList;
public LinkedList() {
this.head = null;
90
this.size = 0;
}
91
}
size--;
}
92
6. Se desea implementar una clase en Java que represente un árbol binario de
búsqueda de números enteros. La clase debe tener los siguientes métodos:
• insert(int x): Inserta un elemento en el árbol binario de búsqueda.
• remove(int x): Elimina un elemento del árbol binario de búsqueda.
• contains(int x): Indica si el árbol binario de búsqueda contiene el elemento x.
• size(): Devuelve el número de elementos en el árbol binario de búsqueda.
• clear(): Elimina todos los elementos del árbol binario de búsqueda.
• inOrderTraversal(): Devuelve una lista con los elementos del árbol binario de
búsqueda en orden ascendente.
• preOrderTraversal(): Devuelve una lista con los elementos del árbol binario de
búsqueda en preorden.
• postOrderTraversal(): Devuelve una lista con los elementos del árbol binario
de búsqueda en postorden.
La clase deberá tener un constructor por defecto que cree un árbol binario de búsqueda
vacío.
package org.example;
public ArbolBinarioBusqueda() {
raiz = null;
size = 0;
}
93
return raiz;
}
return raiz;
}
raiz.valor = minValue(raiz.derecho);
return raiz;
}
94
public boolean contains(int valor) {
return containsRec(raiz, valor);
}
if (valor == raiz.valor)
return true;
95
private int preOrderTraversalRec(Nodo raiz, int[] lista, int
index) {
if (raiz != null) {
lista[index++] = raiz.valor;
index = preOrderTraversalRec(raiz.izquierdo, lista,
index);
index = preOrderTraversalRec(raiz.derecho, lista,
index);
}
return index;
}
96
7. Se te pide que implementes una clase en Java llamada MyArrayList que simule el
comportamiento de un ArrayList en Java. La clase deberá tener los siguientes
métodos públicos:
• MyArrayList(): constructor por defecto que inicializa un ArrayList vacío.
• MyArrayList(int initialCapacity): constructor que inicializa un ArrayList
con la capacidad especificada.
• int size(): devuelve el número de elementos en el ArrayList.
• boolean isEmpty(): devuelve true si el ArrayList está vacío, false en caso
contrario.
• boolean contains(Object o): devuelve true si el ArrayList contiene el objeto
especificado, false en caso contrario.
• int indexOf(Object o): devuelve el índice de la primera aparición del objeto
especificado en el ArrayList, o -1 si el objeto no está presente.
• int lastIndexOf(Object o): devuelve el índice de la última aparición del
objeto especificado en el ArrayList, o -1 si el objeto no está presente.
• Object[] toArray(): devuelve un array con los elementos del ArrayList.
• Object get(int index): devuelve el elemento en la posición especificada en el
ArrayList.
• Object set(int index, Object element): reemplaza el elemento en la
posición especificada en el ArrayList con el elemento especificado, y devuelve el
elemento original.
• boolean add(Object o): agrega el objeto especificado al final del ArrayList, y
devuelve true.
• void add(int index, Object element): agrega el elemento especificado en
la posición especificada en el ArrayList. Los elementos a partir de esa posición se
desplazan hacia la derecha.
• boolean remove(Object o): elimina la primera aparición del objeto
especificado en el ArrayList, si está presente. Devuelve true si se encontró y eliminó
el objeto, false en caso contrario.
• Object remove(int index): elimina el elemento en la posición especificada en
el ArrayList, y devuelve el elemento eliminado.
• void clear(): elimina todos los elementos del ArrayList.
Deberás implementar la clase MyArrayList y todos sus métodos.
Nota: puedes utilizar arrays de Java para implementar el almacenamiento de los elementos
en la clase MyArrayList.
package org.example;
public MyArrayList() {
97
this.array = new Object[10];
this.size = 0;
}
98
return i;
}
}
} else {
for (int i = this.size - 1; i >= 0; i--) {
if (o.equals(this.array[i])) {
return i;
}
}
}
return -1;
}
94
if (index < 0 || index > this.size) {
throw new IndexOutOfBoundsException("Index out of
bounds: " + index);
}
if (this.size == this.array.length) {
Object[] newArray = new Object[this.array.length * 2];
System.arraycopy(this.array, 0, newArray, 0,
this.array.length);
this.array = newArray;
}
System.arraycopy(this.array, index, this.array, index + 1,
this.size - index);
this.array[index] = element;
this.size++;
}
10O
8. Se te pide que implementes una clase en Java llamada ArraySorter que ordene un
array de enteros utilizando el algoritmo de ordenamiento "Bubble Sort". La clase
debe tener los siguientes métodos públicos:
• ArraySorter(int[] array): constructor que recibe el array de enteros a
ordenar.
• void bubbleSort(): método que ordena el array utilizando el algoritmo de
Bubble Sort.
El algoritmo de Bubble Sort funciona de la siguiente manera:
- Compara el primer elemento con el segundo. Si el primer elemento es mayor que el
segundo, intercambia los elementos.
- Compara el segundo elemento con el tercero. Si el segundo elemento es mayor que
el tercero, intercambia los elementos.
- Repite el paso anterior para los elementos restantes del array (es decir, compara el
tercer elemento con el cuarto, el cuarto con el quinto, etc.).
- Continúa repitiendo los pasos 1-3 hasta que ningún intercambio sea necesario
package org.example;
while (swapped) {
swapped = false;
for (int i = 0; i < n - 1; i++) {
if (this.array[i] > this.array[i + 1]) {
int temp = this.array[i];
this.array[i] = this.array[i + 1];
this.array[i + 1] = temp;
swapped = true;
}
}
n--;
}
}
}
101
9. Se te pide que implementes una clase en Java llamada CardDeck que represente
una baraja de cartas. La clase debe tener los siguientes métodos públicos:
• void shuffle(): método que mezcla las cartas de la baraja.
• Card drawCard(): método que devuelve la carta en la parte superior de la baraja
y la elimina de la misma.
• void returnCard(Card card): método que devuelve una carta a la parte
inferior de la baraja.
La clase Card ya está definida y tiene los siguientes atributos:
@Override
public String toString() {
return rank + " of " + suit;
}
}
ackage org.example.card;
import java.util.Random;
102
private final Random random;
public CardDeck() {
this.cards = new Card[52];
this.topIndex = 51;
this.random = new Random();
int index = 0;
for (String suit : Card.suits) {
for (int rank = 1; rank <= 13; rank++) {
cards[index] = new Card(suit, rank);
index++;
}
}
}
103
cards[j] = temp;
}
}
10. Se te pide que implementes un programa en Java que mantenga una lista de socios
de una sociedad y que permita la creación, modificación y eliminación de dichos
socios. Además, deberás implementar una clase ComiteGestor que actúe como
gestor de la sociedad y que permita la generación de un documento de mención de
honor para los socios que hayan cumplido con ciertos estándares.
La clase Socio tiene los siguientes atributos:
104
package org.example.sociedad;
public class Sociedad {
private Socio[] listaSocios;
private int numSocios;
public Sociedad() {
listaSocios = new Socio[100]; // Tamaño inicial del array
numSocios = 0;
}
105
public Socio buscarSocio(int id) {
for (int i = 0; i < numSocios; i++) {
if (listaSocios[i].getId() == id) {
return listaSocios[i];
}
}
return null;
}
106
public int getId() {
return id;
}
107
}
private ComiteGestor() {
this.estandar = 0.0;
}
108
11. Supongamos que ahora se te pide que implementes un programa en Java para una
tienda online que venda productos. Cada producto tendrá un código único, nombre,
descripción, precio y cantidad disponible en inventario. Además, deberás
implementar una clase CarritoDeCompras que permita a los clientes añadir
productos a su carrito y hacer la compra final.
La clase Producto tiene los siguientes atributos:
109
• void establecerDescuentoPorPrecio(double precio, double
descuento): método que establece un descuento en porcentaje para los
productos que tengan un precio superior a un valor determinado.
• double calcularDescuento(Producto producto, int cantidad):
método que calcula el descuento a aplicar a un producto en base a la cantidad que
se vaya a comprar.
• double calcularDescuento(Producto producto): método que calcula el
descuento a aplicar a un producto en base a su precio.
package org.example.tiendaonline;
public TiendaOnline() {
this.inventario = new Producto[tamanoInventario];
this.cantidadProductos = 0;
}
10
System.out.println("No se encontró un producto con el
código " + codigo + " en el inventario.");
}
}
}
package org.example.tiendaonline;
14
public String getNombre() {
return nombre;
}
@Override
public String toString() {
return "Código: " + this.codigo + ", Nombre: " + this.nombre
+ ", Descripción: " + this.descripcion + ", Precio: $" + this.precio
+ ", Cantidad: " + this.cantidad;
}
}
package org.example.tiendaonline;
122
producto.getCodigo()) {
indexProducto = i;
break;
}
}
// Si el producto ya existe en el carrito, sumamos la
cantidad
if (indexProducto != -1) {
this.productos[indexProducto].setCantidad(this.productos[indexProduc
to].getCantidad() + cantidad);
} else {
// Si el producto no existe en el carrito, lo
agregamos
Producto productoEnCarrito = new
Producto(producto.getCodigo(), producto.getNombre(),
producto.getDescripcion(), producto.getPrecio(), cantidad);
this.productos[this.cantidadProductos] =
productoEnCarrito;
this.cantidadProductos++;
}
} else {
System.out.println("No se pueden agregar más productos
al carrito, ha alcanzado el límite.");
}
}
if (indexProducto != -1) {
// Si la cantidad a eliminar es mayor o igual a la
cantidad en el carrito, eliminamos el producto del carrito
if (cantidad >=
this.productos[indexProducto].getCantidad()) {
for (int i = indexProducto; i <
this.cantidadProductos - 1; i++) {
this.productos[i] = this.productos[i+1];
123
}
this.productos[this.cantidadProductos - 1] = null;
this.cantidadProductos--;
} else {
// Si la cantidad a eliminar es menor que la
cantidad en el carrito, restamos la cantidad
this.productos[indexProducto].setCantidad(this.productos[indexProduc
to].getCantidad() - cantidad);
}
} else {
System.out.println("El producto no está en el
carrito.");
}
}
124
this.precioMinimo = precioMinimo;
this.descuentoPrecio = descuentoPrecio;
}
public void establecerDescuentoPorCantidad(int cantidad, double
descuento) {
this.cantidadMinimaDescuento = cantidad;
this.descuentoCantidad = descuento;
}
tienda.agregarProducto(p1);
tienda.agregarProducto(p2);
tienda.agregarProducto(p3); } } }
125
Ejercicios
Prácticos
1. Dado el siguiente código, suponiendo que todas las clases implicadas están
correctamente implementadas y que el método obtenerFechas() devuelve un array de
tipo LocalDate de cualquier longitud, implemente (sin retocar mas líneas de las
indicadas):
(a) Un código equivalente al de las líneas 13-15, utilizando un bucle for clásico.
public class Bucles {
public LocalDate[] obtenerFechas() {
// código para obtener las fechas
}
126
MRAR ejo de Ejemplos Tipo . . . . . . . .
p. 184-108
(a) ¿Como se implementaría la relación entre Socio y Estandar utilizando Java? Asume
que lato el codigo a excepción de la pregunta aquí expuesta esta implementado
(b) ¿Como se implementaría la relación entre sociedad y socio utilizando Java? Asuma que
todo el código a excepción de la pregunta aquí expuesta está implementado.
(c) Implemente en Java la relación entre Sociedad y Documento Mercantil asumiendo una
relación 1:1 y aplicando los principios de la Programación Orientada a Objetos. Asuma
que todo el código a excepción de la pregunta aqui expuesta está implementado
127
(d) Implemente el método añadir Socio gestionando los eventos no descados que
potencialmente pudiesen ocurrir, si aplica. Si necesita alguna otra modificación en el
código que no está representada en el UML, restícela como considere, en UML o
utilizando la sintaxis de Java.
128
3. Dado el sigulente códico fuente, se le solicita que explique y justifique qué
sucede en ciertas líneas concretas de la clase Test. Para cada trozo de codigo
debera responder a las siguientes preguntas:
129
• ¿Qué sucede en esas líneas de código? Justifique su respuesta.
• ¿esas lineas de codigo compilan o no compilan? Justifique sus razones.
• Si las líneas compilasen: indique y justifique la salida que se producirá al ejecutarlas.
• Si las líneas no compilan, opcionalmente puede modificarlas para que compilen.
Para justificar sus respuestas deberá hacer referencia a las características de la programación
orientada a objctos o programación en Java que aplican en cada uno de esos casos (como:
relaciones de herencia, polimorfismo, sobrescritura de métodos,
En esta línea de código se crea un objeto de la clase abstracta FormaGeometrica y se llama al método
identidad() de la misma. Sin embargo, como la clase es abstracta, no se puede instanciar un objeto de
ella y esto generaría un error de compilación.
En esta línea se crea un objeto de la clase Cuadrado y se asigna a la variable de tipo FormaGeometrica
'forma'. Luego se llama al método identidad() del objeto creado. Dado que Cuadrado hereda de
Rectangulo, que hereda de FormaGeometrica, se utiliza polimorfismo para llamar al método identidad()
del objeto de tipo Cuadrado. La salida sería: "Soy forma geometrica. *Y, ademas, soy rectangulo *Soy
cuadrado."
En esta línea se crea un objeto de la clase Rectangulo y se asigna a la variable 'rectangulo'. Luego se
llama al método identidad() del objeto creado. Al llamar al método identidad() de un objeto de tipo
Rectangulo, se utiliza la implementación del método de la clase Rectangulo. La salida sería: "Soy forma
geometrica. *Y, ademas, soy rectangulo".
En esta línea se recorre el arreglo 'formas' con un bucle for-each y se llama al método identidad() de
cada objeto en el arreglo. Debido al polimorfismo, se llamará al método identidad() de cada objeto
correspondiente a su clase concreta. Por lo tanto, la salida sería: "Soy forma geometrica. *Y, ademas,
soy rectangulo *Soy cuadrado." para el primer objeto (de tipo Cuadrado), y "Soy forma geometrica.
*Soy triangulo. Nombre: null" para el segundo objeto (de tipo Triangulo).
130
4. Los Metabólitos son compuesto, generalmente orgánicos, que participan ea los
reacciones químicas que tienen lugar en el organismo (concretamente en aquellas
relacionadas con el metabolismo). Se desea implementar una aplicación para una
asignatura de química analítica que permita trabajar con este tipo de elementos.
Para ello, será necesaria la programación de ciertas clases que modelen dichos
datos y de un programa principal que, en un prmer momento, servirá para
comprobar la validez de dichas clases.
A lo largo del ejercicio, asegurese de que sus clases respetan el principio de
encapsula mento que reutiliza al maximo todo el código que escriba. Por otra parte,
el código debera estar correctamente estructurado en métodos.
Tenga en cuenta que, al final del enunciado. se le proporcionan métodos auxiliares
que podrás utilizar para resover el ejercicio.
131
-La clase Metabolito deberá proporcionar los siguientes constructores:
• Un constructor que recibirá como parámetros: la fórmula del metabolito, su peso
molocular y su nombre.
• Un constructor que recibirá como parámetros la fórmula del metabolito y su peso
molecular.
• Un constructor que recibirá como parámetros solo la fórmula del metabolico y cálcule
el peso molecular.
(b) Programe otra clase denominada Metabolito Primario, que es un tipo más
especializado de Metabolito. Esta nueva clase:
• Tiene los mismos atributos y métodos que la clase Metabolito.
. Posee un atributo denominado tipo que solo podrá tener los valores: LIPIDO
PROTEINA, CARBOHIDRATO.
132
• Tiene un único constructor que recibe TODOS los datos necesarios para inicializas
un MetabolitoPrimario.
• Un Método gel Tipo que devuelva el tipo de metabolito.
• Un metodo tostring que, además de la funcionalidad del método toString de la clase
Metabolito, añada el atributo tipo.
• Un metodo toCSV que, además de la funcionalidad del método toCSV de la clase
Metabolito, ariada el valor del atributo tipo.
• La clase Metacolito Primario tendrá una función fromCSV que devuelva un objeto de
tipo Metadolito Primario donde se reciba un String con formato CSV (comma separated
values) y lo transforme para crear el MetabolitoPrimorio correspondiente
Para la realización de este apartado, suponga que la clase Metabolito ha sido progra
mada satisfactoriamente
(c) Programé otra clase denominada ProgramaPrincipal que contensa un método main
que se encargue de solicitar al usuario si desea:
1. Cargar un fichero de MetabolitoPrimario.
2. Introducir un número de elementos (solicitado al usuario) de tipo MetabolitoPrimario,
los almacene en memoria y, posteriormente, los muestre por pantalla.
3. Introducir un número de elementos (solicitado al usuario) de tipo MetabolitoPrimario,
los almacene en memoria y, posteriormente los guarde en un fichero CSV.
Para la realización de este apartado, suponga que las clases Metabolito y Metabolito-
Primario han sido programadas satisfactoriamente.
133
(a) public class Metabolito {
private String formulaQuimica;
private double pesoMolecular;
private String nombreCompuesto;
private String[] elementos; // arreglo para almacenar los elementos de la formula quimica
private int[] cantidades; // arreglo para almacenar las cantidades de los elementos de la formula quimica
// Constructor que recibe como parametros la formula del metabolito, su peso molecular y su nombre
public Metabolito(String formulaQuimica, double pesoMolecular, String nombreCompuesto) throws
Exception {
this.formulaQuimica = formulaQuimica;
this.pesoMolecular = pesoMolecular;
this.nombreCompuesto = nombreCompuesto;
parseFormula(formulaQuimica); // parsear la formula y almacenar los elementos y cantidades
}
// Constructor que recibe como parametros la formula del metabolito y su peso molecular
public Metabolito(String formulaQuimica, double pesoMolecular) throws Exception {
this(formulaQuimica, pesoMolecular, null); // llamar al constructor con tres parametros y establecer el
nombre en null
}
// Constructor que recibe como parametro solo la formula del metabolico y la calcula
public Metabolito(String formulaQuimica) throws Exception {
this(formulaQuimica, calculateMolecularWeight(formulaQuimica));
}
this.formulaQuimica = formulaQuimica;
this.pesoMolecular = calculateMolecularWeight(formulaQuimica); // recalcular el peso molecular
this.nombreCompuesto = null; // borrar el nombre del compuesto
// Metodo para calcular la masa molecular del compuesto cuya formula se pasa como parametro
public static double calculateMolecularWeight(String formula) throws Exception {
if (formula == null || formula.isEmpty()) {
}
throw new Exception("La fórmula no puede ser nula o vacía.");
134
double molecularWeight = 0.0;
String[] tokens = formula.split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)"); // separar la formula en
elementos y cantidades
switch (token) {
case "SUMA":
resultado += valor;
break;
case "RESTA":
resultado -= valor;
break;
case "MULTIPLICA":
resultado *= valor;
break;
case "DIVIDE":
resultado /= valor;
break;
default:
135
b)
@Override
public String toString() {
return super.toString() + "\nTipo: " + tipo.name();
}
@Override
public String toCSV() {
return super.toCSV() + "," + tipo.name();
}
136
import java.io.*;
C import java.util.*;
switch (opcion) {
case 1:
cargarFichero();
break;
case 2:
int numElementos = Utils.leerEntero(scanner, "Introduzca el número de elementos: ");
List<MetabolitoPrimario> metabolitos = new ArrayList<>();
for (int i = 0; i < numElementos; i++) {
MetabolitoPrimario metabolito = crearMetabolito(scanner);
metabolitos.add(metabolito);
}
mostrarMetabolitos(metabolitos);
break;
case 3:
numElementos = Utils.leerEntero(scanner, "Introduzca el número de elementos: ");
metabolitos = new ArrayList<>();
for (int i = 0; i < numElementos; i++) {
MetabolitoPrimario metabolito = crearMetabolito(scanner);
metabolitos.add(metabolito);
}
guardarMetabolitos(metabolitos);
break;
default:
System.out.println("Opción no válida.");
break;
}
scanner.close();
}
scanner.close();
} 136
private static MetabolitoPrimario crearMetabolito(Scanner scanner) {
String nombre = Utils.leerCadena(scanner, "Introduzca el nombre del metabolito: ");
String formula = Utils.leerCadena(scanner, "Introduzca la fórmula química del metabolito: ");
double masaMolecular = calcularMasaMolecular(formula);
String tipoMetabolito = Utils.leerCadena(scanner, "Introduzca el tipo de metabolito (LIPIDO,
PROTEINA o CARBOHIDRATO): ");
MetabolitoPrimario.Tipo tipo = MetabolitoPrimario.Tipo.valueOf(tipoMetabolito.toUpperCase());
return new MetabolitoPrimario(nombre, formula, masaMolecular, tipo);
}
char c = formula.charAt(index);
// Keep adding characters to the string builder until a non-letter character is found
while (index < formula.length() && Character.isLetter(formula.charAt(index))) {
sb.append(formula.charAt(index));
index++;
}
// Get the atomic mass of the element and add it to the total mass
totalMass += Utils.getAtomicMass(sb.toString());
}
// Check if the character is a digit
else if (Character.isDigit(c)) {
StringBuilder sb = new StringBuilder();
// Keep adding digits to the string builder until a non-digit character is found
while (index < formula.length() && Character.isDigit(formula.charAt(index))) {
sb.append(formula.charAt(index));
index++;
}
// Recursively calculate the mass of the contents of the parentheses and add it to the total mass
totalMass += calculateMass(formula.substring(index), 1);
137
// Skip past the closing parenthesis
while (index < formula.length() && formula.charAt(index) != ')') {
index++;
}
index++;
}
// Check if the character is a closing parenthesis or any other non-letter or non-digit
character
else {
index++;
}
138
•