Skip to content

Commit 77be69d

Browse files
committed
utilize ThreadLocal to reuse DecimalFormat for thread call
1 parent 290605b commit 77be69d

1 file changed

Lines changed: 29 additions & 31 deletions

File tree

  • query/display-number/src/main/java/me/hsgamer/topper/query/display/number

query/display-number/src/main/java/me/hsgamer/topper/query/display/number/NumberDisplay.java

Lines changed: 29 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ private static Map<String, String> getSettings(String query) {
4444
}
4545

4646
private static Function<Number, String> createDisplayFunction(String formatQuery) {
47+
if (formatQuery.isEmpty()) {
48+
ThreadLocal<DecimalFormat> threadLocalFormat = ThreadLocal.withInitial(() -> new DecimalFormat("#.##"));
49+
return n -> threadLocalFormat.get().format(n);
50+
}
51+
4752
if (formatQuery.startsWith(FORMAT_QUERY_SHORTEN)) {
4853
String config = formatQuery.substring(FORMAT_QUERY_SHORTEN.length());
4954
NavigableMap<Double, String> suffixMap = new TreeMap<>();
@@ -158,48 +163,46 @@ private static Function<Number, String> createDisplayFunction(String formatQuery
158163
if (formatQuery.startsWith(FORMAT_QUERY_DECIMAL)) {
159164
Map<String, String> settings = getSettings(formatQuery.substring(FORMAT_QUERY_DECIMAL.length()));
160165

161-
DecimalFormatSymbols symbols = new DecimalFormatSymbols();
162-
DecimalFormat decimalFormat = new DecimalFormat();
163-
decimalFormat.setRoundingMode(RoundingMode.HALF_EVEN);
164-
165-
Optional.ofNullable(settings.get("decimalSeparator"))
166-
.map(s -> s.charAt(0))
167-
.ifPresent(symbols::setDecimalSeparator);
168-
Optional.ofNullable(settings.get("groupingSeparator"))
169-
.map(s -> s.charAt(0))
170-
.ifPresent(c -> {
171-
symbols.setGroupingSeparator(c);
172-
decimalFormat.setGroupingUsed(true);
173-
});
174-
Optional.ofNullable(settings.get("groupingSize"))
166+
final Optional<Character> decimalSeparatorOpt = Optional.ofNullable(settings.get("decimalSeparator"))
167+
.map(s -> s.charAt(0));
168+
final Optional<Character> groupingSeparatorOpt = Optional.ofNullable(settings.get("groupingSeparator"))
169+
.map(s -> s.charAt(0));
170+
final Optional<Integer> groupingSizeOpt = Optional.ofNullable(settings.get("groupingSize"))
175171
.flatMap(s -> {
176172
try {
177173
return Optional.of(Integer.parseInt(s));
178174
} catch (NumberFormatException e) {
179175
return Optional.empty();
180176
}
181-
})
182-
.map(Number::intValue)
183-
.ifPresent(decimalFormat::setGroupingSize);
184-
Optional.ofNullable(settings.get("maximumFractionDigits"))
177+
});
178+
final Optional<Integer> maximumFractionDigitsOpt = Optional.ofNullable(settings.get("maximumFractionDigits"))
185179
.flatMap(s -> {
186180
try {
187181
return Optional.of(Integer.parseInt(s));
188182
} catch (NumberFormatException e) {
189183
return Optional.empty();
190184
}
191-
})
192-
.map(Number::intValue)
193-
.ifPresent(decimalFormat::setMaximumFractionDigits);
194-
195-
decimalFormat.setDecimalFormatSymbols(symbols);
185+
});
196186

197-
return n -> ((DecimalFormat) decimalFormat.clone()).format(n);
187+
ThreadLocal<DecimalFormat> threadLocalFormat = ThreadLocal.withInitial(() -> {
188+
DecimalFormatSymbols sym = new DecimalFormatSymbols();
189+
decimalSeparatorOpt.ifPresent(sym::setDecimalSeparator);
190+
groupingSeparatorOpt.ifPresent(sym::setGroupingSeparator);
191+
DecimalFormat fmt = new DecimalFormat();
192+
fmt.setRoundingMode(RoundingMode.HALF_EVEN);
193+
groupingSeparatorOpt.ifPresent(c -> fmt.setGroupingUsed(true));
194+
groupingSizeOpt.ifPresent(fmt::setGroupingSize);
195+
maximumFractionDigitsOpt.ifPresent(fmt::setMaximumFractionDigits);
196+
fmt.setDecimalFormatSymbols(sym);
197+
return fmt;
198+
});
199+
return n -> threadLocalFormat.get().format(n);
198200
}
199201

200202
try {
201-
DecimalFormat decimalFormat = new DecimalFormat(formatQuery);
202-
return n -> ((DecimalFormat) decimalFormat.clone()).format(n);
203+
new DecimalFormat(formatQuery); // validate the pattern eagerly
204+
ThreadLocal<DecimalFormat> threadLocalFormat = ThreadLocal.withInitial(() -> new DecimalFormat(formatQuery));
205+
return n -> threadLocalFormat.get().format(n);
203206
} catch (IllegalArgumentException e) {
204207
return n -> "INVALID_FORMAT";
205208
}
@@ -213,11 +216,6 @@ private static Function<Number, String> createDisplayFunction(String formatQuery
213216
return getDisplayNullValue();
214217
}
215218

216-
if (formatQuery.isEmpty()) {
217-
DecimalFormat decimalFormat = new DecimalFormat("#.##");
218-
return decimalFormat.format(value);
219-
}
220-
221219
if (formatQuery.equals("raw")) {
222220
return String.valueOf(value);
223221
}

0 commit comments

Comments
 (0)