Large methods is very difficult to read and understand. So methods should be short, between 5-15 lines. And it's important for you to remember that one method should be responsible for one task.
For example: "write to file" or "create report" - are a separate operations. So we should create separate methods for them.
Correct method names is first step to pure code.
Keep in mind that String concatenation creates many new objects that take up a lot of memory if you use it inside of a loop. Though it's safe to use it outside of a loop, because compiler will replace it with StringBuilder anyway java doc
substring()
messes the code in this task.
If you have strange strings or numbers in the code, it's better to declare them as constants. The name of the constant should display this object's purpose.
If you are counting something in your method for example using some variable for the result, don't make this variable a class field.
The class fields should represent the state of the class objects otherwise they should be local variables.
Remember, if you are using classes that implement an AutoCloseable interface, we should use it with try-with-resources.
Avoid opening connection to file in try block inside of another try block. We should keep opened connection to resource as short as possible. In code if you need to read and write to different files - do this in separate try blocks that are not located inside each other.
If the method has only a utility purpose and is used only inside the same class, it should not be
public
. Keep your code as close as possible to follow the encapsulation principle.
Leaving empty catch block or e.printStackTrace
here is a bad practice.
Better re-throw RuntimeException
with original exception and some message in the parameters:
catch (Exception e) {
throw new RuntimeException("Can't read data from the file " + fileName, e);
}