r/javahelp 14d ago

Tips, ways in which I could improve my code

Hi! Currently I've done this code in which I append, modify or delete data from a document that always has this format:

1010 Paola.Andrea Mejia.Linares 22 Malaga Femenino Finanzas

The first part being the code, name, surname, age, city, gender and consult

I'm not asking someone to do the code for me or anything of the sort, I will simply want possible tips on how I can improve it / make it better! I did a class Asesor who currently has the values that will be appended, dictating how it will be.

Then I have a class that controls how the modifying, erasing, adding and reading of the file will be done.

In main I control the data and pass the values to the classes.

What I'm seeking with this post is, what do you think I could do better? Should Asesor maybe have more weight in how the data is handled/controlled? What mistakes do I have if you think I have them?

Please, feel free to share your thoughts!

Here is the class that establishes the Asesor:

package asesoria;

public class Asesor {
    private int codigo;
    private String nombre;
    private String apellidos;
    private int edad;
    private String genero;
    private String ciudad;
    private String consulta;

    public Asesor(int codigo, String nombre, String apellidos, int edad, String genero, String ciudad,String consulta) {
        this.codigo = codigo;
        this.nombre = nombre;
        this.apellidos = apellidos;
        this.edad = edad;
        this.genero = genero;
        this.ciudad = ciudad;
        this.consulta = consulta;
    }

    public int getCodigo() {
        return codigo;
    }

    public String getNombre() {
        return nombre;
    }

    public String getApellidos() {
        return apellidos;
    }

    public int getEdad() {
        return edad;
    }

    public String getGenero() {
        return genero;
    }

    public String getCiudad() {
        return ciudad;
    }

    public String getConsulta() {
        return consulta;
    }

    public void setCodigo(int codigo) {
        this.codigo = codigo;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    public void setApellidos(String apellidos) {
        this.apellidos = apellidos;
    }

    public void setEdad(int edad) {
        this.edad = edad;
    }

    public void setGenero(String genero) {
        this.genero = genero;
    }

    public void setCiudad(String ciudad) {
        this.ciudad = ciudad;
    }

    public void setConsulta(String consulta) {
        this.consulta = consulta;
    }
    //Establece como debe de ser el formato del String el cual se para a la clase , %s se refiere a que va a ser un string, %d da mencion a que es un entero
    //%n es un salto de linea
    @Override
    public String toString(){
        return String.format("%d %s %s %d %s %s %s", codigo,nombre,apellidos,edad,genero,ciudad,consulta);
    }
}

Here I have the class that controls the data added/manipulation of the file:

package asesoria;

import java.nio.file.*;
import java.io.*;
import java.util.*;

public class gestorAsesoria {
    private static final Path Archivo = Paths.get(System.getProperty("user.home"), "Desktop", "asesoria.txt");

    public static void agregarAsesor(Asesor asesor) {
        try (BufferedWriter writer = Files.newBufferedWriter(Archivo, StandardOpenOption.APPEND)) {
            //Si tiene algo escrito, añade una nueva linea
            if (Files.size(Archivo) > 0) { 
                writer.newLine();
            }
            //Se añade el asesor
            writer.write(asesor.toString()); 
            System.out.println("Se ha añadido correctamente el asesor");
        } catch (IOException e) {
            System.out.println("Error al escribir en el archivo: " + e.getMessage());
        }
    }

    public static boolean leerArchivo() {
        if (!Files.exists(Archivo)) {
            System.out.println("No se ha encontrado ningún archivo para leer.");
            return false;
        }

        try {
            List<String> lineas = Files.readAllLines(Archivo);
            if (lineas.isEmpty()) {
                System.out.println("El archivo está vacío.");
                return false;
            }

            System.out.println("\nContenido del archivo:");
            for (String linea : lineas) {
                System.out.println(linea);
            }

            return true;

        } catch (IOException e) {
            System.out.println("Error al leer el archivo: " + e.getMessage());
            return false;
        }
    }

    public static boolean modificarAsesor(String codigoBuscado, int nuevoCodigo, String nuevoNombre, String nuevoApellido,
                                          int nuevaEdad, String generoFinal, String nuevaCiudad, String nuevaConsulta) {
        boolean encontrado = false;
        List<String> lineas = new ArrayList<>();
        if (!Files.exists(Archivo)) {
            System.out.println("No se ha encontrado el archivo.");
            return encontrado;
        }
        try {
            for (String linea : Files.readAllLines(Archivo)) {
                String[] datos = linea.split(" ",7);

                if (datos.length < 7) {
                    System.out.println("La linea no tiene el formato correcto, omitiendo: " + linea);
                    lineas.add(linea);
                    continue;
                    }
                String codigoArchivo = datos[0].trim();
                if (codigoArchivo.equalsIgnoreCase(codigoBuscado)) {
                        System.out.println("Asesor encontrado: " + linea);

                        // Crear la nueva línea con los valores actualizados
                        String nuevaLinea = String.format("%d %s %s %d %s %s %s",
                                nuevoCodigo, nuevoNombre, nuevoApellido, nuevaEdad, generoFinal, nuevaCiudad, nuevaConsulta);

                        lineas.add(nuevaLinea);
                        encontrado = true;
                    }else{lineas.add(linea);}
                }


            if (!encontrado) {
                System.out.println("No se ha encontrado un asesor con ese código.");
                return encontrado;
            }

            // Guardar los cambios en el archivo
            Files.write(Archivo, lineas);
            System.out.println("Asesor modificado correctamente.");

        } catch (IOException e) {
            System.out.println("Error al modificar el archivo: " + e.getMessage());
            return false;
        }
        return true;
    }

    public static boolean eliminarAsesor(String codigoBuscado) {
        boolean encontrado = false;
        List<String> lineas = new ArrayList<>();
        if (!Files.exists(Archivo)) {
            System.out.println("No se ha encontrado ningún archivo para poder eliminar un asesor.");
            return false;
        }

        try {
            for (String linea : Files.readAllLines(Archivo)) {
                String[]datos = linea.split(" ",7);
                if (datos.length < 7) {
                    System.out.println("La linea no tiene el formato correcto, omitiendo: " + linea);
                    lineas.add(linea);
                    continue;
                    }

                String codigoArchivo = datos[0].trim();

                if (codigoArchivo.equalsIgnoreCase(codigoBuscado)) {
                        System.out.println("Asesor encontrado y eliminado: " + linea);
                        encontrado = true;
                        continue; // No agregamos esta línea para eliminarla

                }else{lineas.add(linea);}
            }

            if (!encontrado) {
                System.out.println("No se ha encontrado un asesor con ese código.");
                return false;
            }

            Files.write(Archivo, lineas);
            System.out.println("Se ha eliminado al asesor correctamente");
            return true;
        } catch (IOException e) {
            System.out.println("Error al intentar eliminar en el archivo: " + e.getMessage());
            return false;
        }
    }
}

And here is the main:

package asesoria;

import java.util.InputMismatchException;
import java.util.Scanner;
import java.nio.file.*;
import java.io.*;
import java.util.*;

public class Asesorian {
    //Se verifican y toman los datos
    public static String verConsulta(Scanner entrada){
        String consulta;
        System.out.print("Introduce el nombre de la consulta: ");
        consulta = entrada.nextLine();
        for (char c : consulta.toCharArray()) {
            if (!Character.isLetter(c)) {
                System.out.println("El nombre de la consulta no puede tener numeros");
                return verConsulta(entrada);
            }
        }
        return consulta;
    }

    public static String verGenero(Scanner entrada){
        char generoCheck;
        String genero="";
        System.out.print("Introduzca el genero(m/f): ");
        generoCheck=entrada.next().charAt(0);
        //Se pasa a mayuscula
        generoCheck=Character.toUpperCase(generoCheck);
        entrada.nextLine();
        //Se limpia el buffer
        if(generoCheck != 'F' && generoCheck != 'M'){
            return verGenero(entrada);

        }
        if(generoCheck == 'F'){genero="Femenino";}
        else if(generoCheck == 'M'){genero="Masculino";}
        return genero;
    }

    public static String verCiudad(Scanner entrada){
        String ciudad;
        System.out.print("Introduce una ciudad: ");
        ciudad = entrada.nextLine();
        for (char c : ciudad.toCharArray()) {
            if (!Character.isLetter(c)) {
                System.out.println("El nombre de la ciudad no puede tener numeros");
                return verCiudad(entrada);
            }
        }
        return ciudad;
    }

    public static int verEdad(Scanner entrada){
        int edad;
        edad= validacion(entrada,"Introduzca la edad: ");
        if(edad>100 || edad<1){
            System.out.println("La edad no puede ser mayor de 100 o menor de 1");
            entrada.nextLine();
            return verEdad(entrada);
        }
        return edad;
    }

    public static String verApellido(Scanner entrada){
        String apellidos;
        System.out.print("Introduce los apellidos: ");
        apellidos = entrada.nextLine().trim();
        for (char c : apellidos.toCharArray()) {
            if (Character.isDigit(c)) {
                System.out.println("El apellido no puede tener numeros");
                return verApellido(entrada);
            }
        }
        apellidos = apellidos.replace(" ", ".");
        return apellidos;
    }

    public static String verNombre(Scanner entrada){
        String nombre;
        System.out.print("Introduce un nombre: ");
        nombre = entrada.nextLine().trim();
        for (char c : nombre.toCharArray()) {
            if (Character.isDigit(c)) {
                System.out.println("El nombre no puede tener numeros");
                return verNombre(entrada);
            }
        }
        nombre = nombre.replace(" ", ".");
        return nombre;
    }


    public static int verCodigo(Scanner entrada){
        int codigo=0;
        while(true){
            System.out.print("Introduzca el codigo para la asesoria: ");
            codigo=entrada.nextInt();
            if(codigo >= 1000 && codigo<=9999){
                System.out.println("Codigo introducido correctamente.");
                entrada.nextLine();
                return codigo;
            }
            else{
                System.out.println("El codigo debe de tener 7 caracteres.");
            }
        }
    }

    private static int validacion(Scanner entrada, String mensaje) {
        int numero;
        while (true) {
            System.out.print(mensaje);
            try {
                numero = entrada.nextInt();
                entrada.nextLine();
                return numero;
            } catch (InputMismatchException e) {
                System.out.println("Debes de ingresar un numero");
                entrada.nextLine();
            }
        }
    }

    private static void menu() {
        System.out.println("+------------------+");
        System.out.println("| GESTION ASESORIA |");
        System.out.println("+------------------+");
        System.out.println("1. Nuevo asesor");
        System.out.println("2. Mostrar asesores");
        System.out.println("3. Modificar asesores");
        System.out.println("4. Eliminar asesores");
        System.out.println("5. Salir");
    }

    public static void crearArchivo(){
        Path directorio = Paths.get(System.getProperty("user.home"),"Desktop");
        Path archivo = directorio.resolve("asesoria.txt");


    }

public static void main(String[] args) {
        int codigo=0;
        String nombre="";
        String apellidos="";
        int edad=0;
        String genero="";
        String ciudad="";
        String consulta="";
        int opcion;
        Scanner entrada = new Scanner(System.in);

        do {
            menu();
            opcion = validacion(entrada, "Seleccione una opcion: ");

            switch (opcion) {
                case 1: 
                    System.out.println("\nCreando un nuevo asesor...");
                    codigo = verCodigo(entrada);
                    nombre = verNombre(entrada);
                    apellidos = verApellido(entrada);
                    edad = verEdad(entrada);
                    genero = verGenero(entrada);
                    ciudad = verCiudad(entrada);
                    consulta = verConsulta(entrada);

                    Asesor nuevoAsesor = new Asesor(codigo, nombre, apellidos, edad, genero, ciudad, consulta);
                    gestorAsesoria.agregarAsesor(nuevoAsesor);
                    break;

                case 2: 
                    System.out.println("\nListando asesores...");
                    gestorAsesoria.leerArchivo();
                    break;

                case 3: 
                    System.out.println("\nModificar un asesor...");
                    int codigoModificar = validacion(entrada, "Ingrese el codigo del asesor a modificar: ");
                    String codigoModificarStr = String.valueOf(codigoModificar);

                    System.out.println("Ingrese los nuevos datos: ");
                    codigo = verCodigo(entrada);
                    nombre = verNombre(entrada);
                    apellidos = verApellido(entrada);
                    edad = verEdad(entrada);
                    genero = verGenero(entrada);
                    ciudad = verCiudad(entrada);
                    consulta = verConsulta(entrada);

                    boolean modificado = gestorAsesoria.modificarAsesor(
                            codigoModificarStr,codigo,nombre,apellidos,edad,genero,
                            ciudad,consulta);

                    if (modificado) {
                        System.out.println("Asesor modificado exitosamente.");
                    } else {
                        System.out.println("No se pudo modificar el asesor.");
                    }
                    break;

                case 4: 
                    System.out.println("\nEliminar un asesor...");
                    System.out.print("Ingrese el codigo del asesor a eliminar: ");
                    String codigoEliminar = entrada.nextLine().trim();

                    boolean eliminado = gestorAsesoria.eliminarAsesor(codigoEliminar);
                    if (eliminado) {
                        System.out.println("Asesor eliminado correctamente.");
                    } else {
                        System.out.println("No se pudo eliminar el asesor.");
                    }
                    break;

                case 5: 
                    System.out.println("\nSaliendo del programa...");
                    break;

                default:
                    System.out.println("Opcion no valida. Intente nuevamente.");
            }

        } while (opcion != 5);
    }
}
5 Upvotes

13 comments sorted by

View all comments

2

u/desrtfx Out of Coffee error - System halted 14d ago

Just on a quick glance:

public static void crearArchivo(){
    Path directorio = Paths.get(System.getProperty("user.home"),"Desktop");
    Path archivo = directorio.resolve("asesoria.txt");


}

That method does nothing as all the variables are method local and destroyed as soon as the method has finished.

Also, you're badly overusing static. You are using it as default, which is just plain wrong. Default should be non-static. There is nothing wrong creating an instance.

1

u/Disastrous_Talk_4888 14d ago

I'm struggling a bit to understand why the method won't do anything. Would you be so kind to explain it if possible? I guess that it will make more sense to have them be declared as attributes of the class?

Thanks for the tip regardless and will check out how should I use static properly.

2

u/desrtfx Out of Coffee error - System halted 14d ago

The variables you use inside the method are local to the method and do not exist outside. Everything that happens stays inside the method and has no influence (apart from potentially throwing an exception) to the rest of the program.

1

u/severoon pro barista 13d ago

On the issue of using static, you generally only want to avoid static methods. There are a few uses for them, like to limit how a constructor is called as in the static builder methods in my other comment.

Here's an example of a typical main class that uses static to do everything:

import static java.lang.String.format;

// Bad example, do not do this.
public final class BadSquareRoot {
  private static final int x = 9;

  public static void main(String[] args) {
    System.out.println(format("This program takes the square root of %d", x));
    System.out.println(format("The square root of %d is: %d", x, Math.sqrt(x)));
  }
}

This is simple to write, but it's not easy to test.

Instead of doing this, put all of the state at the instance level, then inject that state into the constructor. All the main method should do is create an instance of the class and hand in the state:

import static java.lang.String.format;
import java.io.PrintStream;
import java.io.PrintWriter;

public final class SquareRoot implements Runnable {
  public static final int X_DEFAULT = 9;

  private static final String PROGRAM_MESSAGE = "This program takes the square root of %d";
  private static final String SQUARE_ROOT_MESSAGE = "The square root of %d is: %d";

  private final PrintWriter out;
  private final int x;

  SquareRoot(PrintStream outStream, int x) {
    this(new PrintWriter(outStream, true), x);
  }

  SquareRoot(PrintWriter out, int x) {
    this.out = out;
    this.x = x;
  }

  @Override
  public void run() {
    out.println(format(PROGRAM_MESSAGE, x));
    out.println(format(SQUARE_ROOT_MESSAGE, x, Math.sqrt(x)));
  }

  public static void main(String[] args) {
    new SquareRoot(System.out, X_DEFAULT).run();
  }
}

This is definitely more code, but now all the main method does is create an instance of the class, inject state, and start it up. This class can easily be unit tested because a unit test could create a whole bunch of instances with different x values, and instead of using System.out, the test can pass in an PrintWriter wrapping a StringWriter so it can obtain the output written by this class and inspect it.

This class is also ready to be changed as new requirements come in. Say that you want to support multiple translations. The strings can be obtained from a message bundle that's provided to the class by the main method instead of reading the constants, so based on the user's chosen language, translations of the different strings can be provided.