You are obviously looking at the wrong end. Even the “optimized” variant
public double roundDecimal(double val, DecimalFormat dFormat) {
return Double.parseDouble(dFormat.format(val));
}
creates multiple objects on each call. On the API side, format returns a new String instance which you pass to parseDouble. Below the surface both operations, format and parseDouble create temporary objects for doing their work. Their implementor(s) had no reason to worry about them, as the tasks of formatting a double to decimal representation and parsing a decimal representation to double are so expensive, that they outweigh anything.
It’s easy to overlook, as for us humans, decimal representations seem to be the most natural thing, but for a computer, converting to a decimal representation and back is very expensive.
But before you continue worrying about the performance, you should start worrying about correctness. Generally, it’s a bad idea to apply the concept formatting to double values. Since their internal representation is fundamentally different to decimal numbers, they can’t represent tenths exactly. If you want a controllable precision of that kind, BigDecimal is the right tool for the job (yes, they are objects…). Or you use the result string of the Formatter for printing or any other UI presentation.
Besides that, by using the format string "#,##0.0", you are requesting a string with a grouping separator which Double.parseDouble does not expect. Further, you are applying the decimal format of the current user’s locale, so if it is not using . as decimal separator, the operation will, break even when the value is too small for grouping. So for English locales, passing the value 1234 is sufficient to break this method, for, e.g. German locales, it will break with every value.
A work-around would be to use the same format for parsing that you used for formatting:
public double roundDecimal(double val, DecimalFormat dFormat) {
try {
return dFormat.parse(dFormat.format(val)).doubleValue();
} catch (ParseException ex) {
throw new AssertionError(ex);
}
}
but this still will have a desastrous performance, not because of the temporary objects created.
After all, if you still want to use double values rather than BigDecimal, the solution is straight-forward:
public double roundDecimal(double val) {
return Math.round(val*10)/10.0;
}