Alternative to create a new method in a String object?

Asked

Viewed 220 times

4

I have the following situation: I have a txt file of defined positions (type CSV, CNAB, etc) to process and extract values. For the purposes of understanding, follow the code I made and it’s working perfectly:

public class Extract {

    final int[] CPF = new int[]{0, 10};
    final int[] NOME = new int[]{15, 45};

    public static void main(String args[]) {

      FileInputStream fis = new FileInputStream("C:\\cnab.txt");        
      String line;

      while ((line = fis.readLine()) != null) {
          System.out.println(getValue(line, CPF));
          System.out.println(getValue(line, NOME)); 
      }
    }

    private String getValue(String line, int[] slice) {
        return line.substring(slice[0], slice[1]);
    }
 }

So far ok, but I’d like something more readable, elegant, such as:

System.out.println(line.getValue(CPF));

But we all know that String is final. Does anyone have any suggestions?

  • 2

    Change the language to C# and be happy :) Otherwise, it is not possible, but it also changes very little. I am glad that String is final, otherwise people would do atrocities as they do with most classes that are not.

  • 1

    Even if you come to use C#, use Extension Methods here would be a great gambiarra. Imagine a String, one of the most cohesive objects of the language, with a method string.getValue(int[])! Defining a new class is a better solution.

2 answers

8


Why shouldn’t you do it

Changing a basic language class (whatever) to implement a simple requirement like this is a big mistake.

The Java language purposely prevents for security reasons that basic types like String and Integer are modified or extended with inheritance. Such classes are declared with the modifier final.

One of the great dangers of this is in relation to organization. Programmers would start making several language modifications, include libraries that would make other modifications and the code would end up a big mess.

Another problem is performance. Large systems would end up with too much overloading of additional methods and subclasses where simply not needed.

Ever wondered if each programmer tried to modify the class String to meet your immediate needs?

Do O right

Inheritance or modification of existing classes nay is the best solution from the point of view of design object-oriented to situations like this.

In this case, you can simply encapsulate the line into a new object containing the method you need.

Example:

public class LinhaArquivo {
    private String linha;
    public LinhaArquivo(String linha) { 
        this.linha = linha;
    }
    public String getValue(int[] slice) {
        return linha.substring(slice[0], slice[1]);
    }
}

Then you could change your code as follows:

public class Extract {

    final int[] CPF = new int[]{0, 10};
    final int[] NOME = new int[]{15, 45};

    public static void main(String args[]) {

      FileInputStream fis = new FileInputStream("C:\\cnab.txt");        
      String line;

      while ((line = br.readLine()) != null) {
          LinhaArquivo linha = new LinhaArquivo(line);
          System.out.println(linha.getValue(CPF));
          System.out.println(linha.getValue(NOME)); 
      }
    }

}
  • 1

    utluiz, maybe I didn’t express myself right, I know why String is final, what the implications are and what, obviously, is not allowed. I just wanted an elegant solution so that the object itself (the line of the txt file) has a method that extracts from itself a certain value from an argument passed as parameter.

  • 4

    Magician. Very good. @dellasavia, in this answer you have exactly what you described: "the object itself (the line of the txt file) has a method that extracts a certain value from itself from an argument passed as parameter". A string is a string, a line is a line. It makes no sense to "specialize" (inherit or extend) a line string. utluiz defined a line object that uses a string - that’s beautiful.

6

If positions are static, create an Enum

public enum ArchiveEnum {

NOME(0, 5),
CPF(6, 20);
private Integer minAge;
private Integer maxAge;

private ArchiveEnum(Integer minAge, Integer maxAge) {
    this.minAge = minAge;
    this.maxAge = maxAge;
}

public Integer getMinAge() {
    return minAge;
}

public void setMinAge(Integer minAge) {
    this.minAge = minAge;
}

public Integer getMaxAge() {
    return maxAge;
}

public void setMaxAge(Integer maxAge) {
    this.maxAge = maxAge;
}
}

And in your method, pass the type of ENUM

public String getCampo(ArchiveEnum enumValue) {
    String archive = "TIAGO,111.111.111-11"; // Suposição de linha do arquivo
    return archive.subString(enumValue.getMinAge(), enumValue.getMaxAge()).toString();
}
  • Bevilaqua, I believe this is the most elegant solution, I will consider your correct answer, but I would create a method within the ENUM called public String extractFrom(String line) that would extract the contents of the String based on the coordinates defined in the constructor of each ENUM and, in my main class, just call System.out.println(ArchiveEnum.NOME.extractFrom(line));.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.