8333396: Use StringBuilder internally for java.text.Format.* formatting
Reviewed-by: naoto, liach, jlu
This commit is contained in:
parent
fd741a88e8
commit
4da9915875
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -54,7 +54,7 @@ class CharacterIteratorFieldDelegate implements Format.FieldDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void formatted(Format.Field attr, Object value, int start, int end,
|
public void formatted(Format.Field attr, Object value, int start, int end,
|
||||||
StringBuffer buffer) {
|
Format.StringBuf buffer) {
|
||||||
if (start != end) {
|
if (start != end) {
|
||||||
if (start < size) {
|
if (start < size) {
|
||||||
// Adjust attributes of existing runs
|
// Adjust attributes of existing runs
|
||||||
@ -93,7 +93,7 @@ class CharacterIteratorFieldDelegate implements Format.FieldDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void formatted(int fieldID, Format.Field attr, Object value,
|
public void formatted(int fieldID, Format.Field attr, Object value,
|
||||||
int start, int end, StringBuffer buffer) {
|
int start, int end, Format.StringBuf buffer) {
|
||||||
formatted(attr, value, start, end, buffer);
|
formatted(attr, value, start, end, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -514,7 +514,13 @@ public class ChoiceFormat extends NumberFormat {
|
|||||||
@Override
|
@Override
|
||||||
public StringBuffer format(long number, StringBuffer toAppendTo,
|
public StringBuffer format(long number, StringBuffer toAppendTo,
|
||||||
FieldPosition status) {
|
FieldPosition status) {
|
||||||
return format((double)number, toAppendTo, status);
|
return format((double) number, StringBufFactory.of(toAppendTo), status).asStringBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
StringBuf format(long number, StringBuf toAppendTo,
|
||||||
|
FieldPosition status) {
|
||||||
|
return format((double) number, toAppendTo, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -531,6 +537,12 @@ public class ChoiceFormat extends NumberFormat {
|
|||||||
@Override
|
@Override
|
||||||
public StringBuffer format(double number, StringBuffer toAppendTo,
|
public StringBuffer format(double number, StringBuffer toAppendTo,
|
||||||
FieldPosition status) {
|
FieldPosition status) {
|
||||||
|
return format(number, StringBufFactory.of(toAppendTo), status).asStringBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
StringBuf format(double number, StringBuf toAppendTo,
|
||||||
|
FieldPosition status) {
|
||||||
// find the number
|
// find the number
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < choiceLimits.length; ++i) {
|
for (i = 0; i < choiceLimits.length; ++i) {
|
||||||
|
@ -552,6 +552,35 @@ public final class CompactNumberFormat extends NumberFormat {
|
|||||||
&& ((BigInteger) number).bitLength() < 64)) {
|
&& ((BigInteger) number).bitLength() < 64)) {
|
||||||
return format(((Number) number).longValue(), toAppendTo,
|
return format(((Number) number).longValue(), toAppendTo,
|
||||||
fieldPosition);
|
fieldPosition);
|
||||||
|
} else if (number instanceof BigDecimal) {
|
||||||
|
return format((BigDecimal) number, StringBufFactory.of(toAppendTo), fieldPosition).asStringBuffer();
|
||||||
|
} else if (number instanceof BigInteger) {
|
||||||
|
return format((BigInteger) number, StringBufFactory.of(toAppendTo), fieldPosition).asStringBuffer();
|
||||||
|
} else if (number instanceof Number) {
|
||||||
|
return format(((Number) number).doubleValue(), toAppendTo, fieldPosition);
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Cannot format "
|
||||||
|
+ number.getClass().getName() + " as a number");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
StringBuf format(Object number,
|
||||||
|
StringBuf toAppendTo,
|
||||||
|
FieldPosition fieldPosition) {
|
||||||
|
|
||||||
|
if (number == null) {
|
||||||
|
throw new IllegalArgumentException("Cannot format null as a number");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (number instanceof Long || number instanceof Integer
|
||||||
|
|| number instanceof Short || number instanceof Byte
|
||||||
|
|| number instanceof AtomicInteger
|
||||||
|
|| number instanceof AtomicLong
|
||||||
|
|| (number instanceof BigInteger
|
||||||
|
&& ((BigInteger) number).bitLength() < 64)) {
|
||||||
|
return format(((Number) number).longValue(), toAppendTo,
|
||||||
|
fieldPosition);
|
||||||
} else if (number instanceof BigDecimal) {
|
} else if (number instanceof BigDecimal) {
|
||||||
return format((BigDecimal) number, toAppendTo, fieldPosition);
|
return format((BigDecimal) number, toAppendTo, fieldPosition);
|
||||||
} else if (number instanceof BigInteger) {
|
} else if (number instanceof BigInteger) {
|
||||||
@ -560,7 +589,7 @@ public final class CompactNumberFormat extends NumberFormat {
|
|||||||
return format(((Number) number).doubleValue(), toAppendTo, fieldPosition);
|
return format(((Number) number).doubleValue(), toAppendTo, fieldPosition);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Cannot format "
|
throw new IllegalArgumentException("Cannot format "
|
||||||
+ number.getClass().getName() + " as a number");
|
+ number.getClass().getName() + " as a number");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -591,12 +620,21 @@ public final class CompactNumberFormat extends NumberFormat {
|
|||||||
public StringBuffer format(double number, StringBuffer result,
|
public StringBuffer format(double number, StringBuffer result,
|
||||||
FieldPosition fieldPosition) {
|
FieldPosition fieldPosition) {
|
||||||
|
|
||||||
|
fieldPosition.setBeginIndex(0);
|
||||||
|
fieldPosition.setEndIndex(0);
|
||||||
|
return format(number, StringBufFactory.of(result), fieldPosition.getFieldDelegate()).asStringBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
StringBuf format(double number, StringBuf result,
|
||||||
|
FieldPosition fieldPosition) {
|
||||||
|
|
||||||
fieldPosition.setBeginIndex(0);
|
fieldPosition.setBeginIndex(0);
|
||||||
fieldPosition.setEndIndex(0);
|
fieldPosition.setEndIndex(0);
|
||||||
return format(number, result, fieldPosition.getFieldDelegate());
|
return format(number, result, fieldPosition.getFieldDelegate());
|
||||||
}
|
}
|
||||||
|
|
||||||
private StringBuffer format(double number, StringBuffer result,
|
private StringBuf format(double number, StringBuf result,
|
||||||
FieldDelegate delegate) {
|
FieldDelegate delegate) {
|
||||||
|
|
||||||
boolean nanOrInfinity = decimalFormat.handleNaN(number, result, delegate);
|
boolean nanOrInfinity = decimalFormat.handleNaN(number, result, delegate);
|
||||||
@ -681,12 +719,21 @@ public final class CompactNumberFormat extends NumberFormat {
|
|||||||
public StringBuffer format(long number, StringBuffer result,
|
public StringBuffer format(long number, StringBuffer result,
|
||||||
FieldPosition fieldPosition) {
|
FieldPosition fieldPosition) {
|
||||||
|
|
||||||
|
fieldPosition.setBeginIndex(0);
|
||||||
|
fieldPosition.setEndIndex(0);
|
||||||
|
return format(number, StringBufFactory.of(result), fieldPosition.getFieldDelegate()).asStringBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
StringBuf format(long number, StringBuf result,
|
||||||
|
FieldPosition fieldPosition) {
|
||||||
|
|
||||||
fieldPosition.setBeginIndex(0);
|
fieldPosition.setBeginIndex(0);
|
||||||
fieldPosition.setEndIndex(0);
|
fieldPosition.setEndIndex(0);
|
||||||
return format(number, result, fieldPosition.getFieldDelegate());
|
return format(number, result, fieldPosition.getFieldDelegate());
|
||||||
}
|
}
|
||||||
|
|
||||||
private StringBuffer format(long number, StringBuffer result, FieldDelegate delegate) {
|
private StringBuf format(long number, StringBuf result, FieldDelegate delegate) {
|
||||||
boolean isNegative = (number < 0);
|
boolean isNegative = (number < 0);
|
||||||
if (isNegative) {
|
if (isNegative) {
|
||||||
number = -number;
|
number = -number;
|
||||||
@ -757,15 +804,15 @@ public final class CompactNumberFormat extends NumberFormat {
|
|||||||
* of the prefix and the suffix fields can be
|
* of the prefix and the suffix fields can be
|
||||||
* obtained using {@link NumberFormat.Field#PREFIX}
|
* obtained using {@link NumberFormat.Field#PREFIX}
|
||||||
* and {@link NumberFormat.Field#SUFFIX} respectively.
|
* and {@link NumberFormat.Field#SUFFIX} respectively.
|
||||||
* @return the {@code StringBuffer} passed in as {@code result}
|
* @return the {@code StringBuf} passed in as {@code result}
|
||||||
* @throws ArithmeticException if rounding is needed with rounding
|
* @throws ArithmeticException if rounding is needed with rounding
|
||||||
* mode being set to {@code RoundingMode.UNNECESSARY}
|
* mode being set to {@code RoundingMode.UNNECESSARY}
|
||||||
* @throws NullPointerException if any of the given parameter
|
* @throws NullPointerException if any of the given parameter
|
||||||
* is {@code null}
|
* is {@code null}
|
||||||
* @see FieldPosition
|
* @see FieldPosition
|
||||||
*/
|
*/
|
||||||
private StringBuffer format(BigDecimal number, StringBuffer result,
|
private StringBuf format(BigDecimal number, StringBuf result,
|
||||||
FieldPosition fieldPosition) {
|
FieldPosition fieldPosition) {
|
||||||
|
|
||||||
Objects.requireNonNull(number);
|
Objects.requireNonNull(number);
|
||||||
fieldPosition.setBeginIndex(0);
|
fieldPosition.setBeginIndex(0);
|
||||||
@ -773,7 +820,7 @@ public final class CompactNumberFormat extends NumberFormat {
|
|||||||
return format(number, result, fieldPosition.getFieldDelegate());
|
return format(number, result, fieldPosition.getFieldDelegate());
|
||||||
}
|
}
|
||||||
|
|
||||||
private StringBuffer format(BigDecimal number, StringBuffer result,
|
private StringBuf format(BigDecimal number, StringBuf result,
|
||||||
FieldDelegate delegate) {
|
FieldDelegate delegate) {
|
||||||
|
|
||||||
boolean isNegative = number.signum() == -1;
|
boolean isNegative = number.signum() == -1;
|
||||||
@ -843,15 +890,15 @@ public final class CompactNumberFormat extends NumberFormat {
|
|||||||
* prefix and the suffix fields can be obtained
|
* prefix and the suffix fields can be obtained
|
||||||
* using {@link NumberFormat.Field#PREFIX} and
|
* using {@link NumberFormat.Field#PREFIX} and
|
||||||
* {@link NumberFormat.Field#SUFFIX} respectively.
|
* {@link NumberFormat.Field#SUFFIX} respectively.
|
||||||
* @return the {@code StringBuffer} passed in as {@code result}
|
* @return the {@code StringBuf} passed in as {@code result}
|
||||||
* @throws ArithmeticException if rounding is needed with rounding
|
* @throws ArithmeticException if rounding is needed with rounding
|
||||||
* mode being set to {@code RoundingMode.UNNECESSARY}
|
* mode being set to {@code RoundingMode.UNNECESSARY}
|
||||||
* @throws NullPointerException if any of the given parameter
|
* @throws NullPointerException if any of the given parameter
|
||||||
* is {@code null}
|
* is {@code null}
|
||||||
* @see FieldPosition
|
* @see FieldPosition
|
||||||
*/
|
*/
|
||||||
private StringBuffer format(BigInteger number, StringBuffer result,
|
private StringBuf format(BigInteger number, StringBuf result,
|
||||||
FieldPosition fieldPosition) {
|
FieldPosition fieldPosition) {
|
||||||
|
|
||||||
Objects.requireNonNull(number);
|
Objects.requireNonNull(number);
|
||||||
fieldPosition.setBeginIndex(0);
|
fieldPosition.setBeginIndex(0);
|
||||||
@ -859,7 +906,7 @@ public final class CompactNumberFormat extends NumberFormat {
|
|||||||
return format(number, result, fieldPosition.getFieldDelegate(), false);
|
return format(number, result, fieldPosition.getFieldDelegate(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private StringBuffer format(BigInteger number, StringBuffer result,
|
private StringBuf format(BigInteger number, StringBuf result,
|
||||||
FieldDelegate delegate, boolean formatLong) {
|
FieldDelegate delegate, boolean formatLong) {
|
||||||
|
|
||||||
boolean isNegative = number.signum() == -1;
|
boolean isNegative = number.signum() == -1;
|
||||||
@ -936,7 +983,7 @@ public final class CompactNumberFormat extends NumberFormat {
|
|||||||
* {@code NumberFormat.Field.SIGN} and
|
* {@code NumberFormat.Field.SIGN} and
|
||||||
* {@code NumberFormat.Field.PREFIX} fields
|
* {@code NumberFormat.Field.PREFIX} fields
|
||||||
*/
|
*/
|
||||||
private void appendPrefix(StringBuffer result, String prefix,
|
private void appendPrefix(StringBuf result, String prefix,
|
||||||
FieldDelegate delegate) {
|
FieldDelegate delegate) {
|
||||||
append(result, expandAffix(prefix), delegate,
|
append(result, expandAffix(prefix), delegate,
|
||||||
getFieldPositions(prefix, NumberFormat.Field.PREFIX));
|
getFieldPositions(prefix, NumberFormat.Field.PREFIX));
|
||||||
@ -952,7 +999,7 @@ public final class CompactNumberFormat extends NumberFormat {
|
|||||||
* {@code NumberFormat.Field.SIGN} and
|
* {@code NumberFormat.Field.SIGN} and
|
||||||
* {@code NumberFormat.Field.SUFFIX} fields
|
* {@code NumberFormat.Field.SUFFIX} fields
|
||||||
*/
|
*/
|
||||||
private void appendSuffix(StringBuffer result, String suffix,
|
private void appendSuffix(StringBuf result, String suffix,
|
||||||
FieldDelegate delegate) {
|
FieldDelegate delegate) {
|
||||||
append(result, expandAffix(suffix), delegate,
|
append(result, expandAffix(suffix), delegate,
|
||||||
getFieldPositions(suffix, NumberFormat.Field.SUFFIX));
|
getFieldPositions(suffix, NumberFormat.Field.SUFFIX));
|
||||||
@ -968,7 +1015,7 @@ public final class CompactNumberFormat extends NumberFormat {
|
|||||||
* @param positions a list of {@code FieldPosition} in the given
|
* @param positions a list of {@code FieldPosition} in the given
|
||||||
* string
|
* string
|
||||||
*/
|
*/
|
||||||
private void append(StringBuffer result, String string,
|
private void append(StringBuf result, String string,
|
||||||
FieldDelegate delegate, List<FieldPosition> positions) {
|
FieldDelegate delegate, List<FieldPosition> positions) {
|
||||||
if (!string.isEmpty()) {
|
if (!string.isEmpty()) {
|
||||||
int start = result.length();
|
int start = result.length();
|
||||||
@ -1134,7 +1181,7 @@ public final class CompactNumberFormat extends NumberFormat {
|
|||||||
public AttributedCharacterIterator formatToCharacterIterator(Object obj) {
|
public AttributedCharacterIterator formatToCharacterIterator(Object obj) {
|
||||||
CharacterIteratorFieldDelegate delegate
|
CharacterIteratorFieldDelegate delegate
|
||||||
= new CharacterIteratorFieldDelegate();
|
= new CharacterIteratorFieldDelegate();
|
||||||
StringBuffer sb = new StringBuffer();
|
StringBuf sb = StringBufFactory.of();
|
||||||
|
|
||||||
if (obj instanceof Double || obj instanceof Float) {
|
if (obj instanceof Double || obj instanceof Float) {
|
||||||
format(((Number) obj).doubleValue(), sb, delegate);
|
format(((Number) obj).doubleValue(), sb, delegate);
|
||||||
|
@ -346,6 +346,19 @@ public abstract class DateFormat extends Format {
|
|||||||
throw new IllegalArgumentException("Cannot format given Object as a Date");
|
throw new IllegalArgumentException("Cannot format given Object as a Date");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
final StringBuf format(Object obj, StringBuf toAppendTo,
|
||||||
|
FieldPosition fieldPosition) {
|
||||||
|
if (obj instanceof Date) {
|
||||||
|
return format((Date) obj, toAppendTo, fieldPosition);
|
||||||
|
} else if (obj instanceof Number) {
|
||||||
|
return format(new Date(((Number) obj).longValue()),
|
||||||
|
toAppendTo, fieldPosition);
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Cannot format given Object as a Date");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Formats a {@link Date} into a date-time string. The formatted
|
* Formats a {@link Date} into a date-time string. The formatted
|
||||||
* string is appended to the given {@code StringBuffer}.
|
* string is appended to the given {@code StringBuffer}.
|
||||||
@ -371,6 +384,11 @@ public abstract class DateFormat extends Format {
|
|||||||
public abstract StringBuffer format(Date date, StringBuffer toAppendTo,
|
public abstract StringBuffer format(Date date, StringBuffer toAppendTo,
|
||||||
FieldPosition fieldPosition);
|
FieldPosition fieldPosition);
|
||||||
|
|
||||||
|
StringBuf format(Date date, StringBuf toAppendTo,
|
||||||
|
FieldPosition fieldPosition) {
|
||||||
|
throw new UnsupportedOperationException("Subclasses should override this method");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Formats a {@link Date} into a date-time string.
|
* Formats a {@link Date} into a date-time string.
|
||||||
*
|
*
|
||||||
@ -379,8 +397,14 @@ public abstract class DateFormat extends Format {
|
|||||||
*/
|
*/
|
||||||
public final String format(Date date)
|
public final String format(Date date)
|
||||||
{
|
{
|
||||||
return format(date, new StringBuffer(),
|
if ("java.text".equals(getClass().getPackageName())
|
||||||
DontCareFieldPosition.INSTANCE).toString();
|
&& "java.text".equals(numberFormat.getClass().getPackageName())) {
|
||||||
|
return format(date, StringBufFactory.of(),
|
||||||
|
DontCareFieldPosition.INSTANCE).toString();
|
||||||
|
} else {
|
||||||
|
return format(date, new StringBuffer(),
|
||||||
|
DontCareFieldPosition.INSTANCE).toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -556,9 +556,9 @@ public class DecimalFormat extends NumberFormat {
|
|||||||
((BigInteger)number).bitLength () < 64)) {
|
((BigInteger)number).bitLength () < 64)) {
|
||||||
return format(((Number)number).longValue(), toAppendTo, pos);
|
return format(((Number)number).longValue(), toAppendTo, pos);
|
||||||
} else if (number instanceof BigDecimal) {
|
} else if (number instanceof BigDecimal) {
|
||||||
return format((BigDecimal)number, toAppendTo, pos);
|
return format((BigDecimal)number, StringBufFactory.of(toAppendTo), pos).asStringBuffer();
|
||||||
} else if (number instanceof BigInteger) {
|
} else if (number instanceof BigInteger) {
|
||||||
return format((BigInteger)number, toAppendTo, pos);
|
return format((BigInteger)number, StringBufFactory.of(toAppendTo), pos).asStringBuffer();
|
||||||
} else if (number instanceof Number) {
|
} else if (number instanceof Number) {
|
||||||
return format(((Number)number).doubleValue(), toAppendTo, pos);
|
return format(((Number)number).doubleValue(), toAppendTo, pos);
|
||||||
} else {
|
} else {
|
||||||
@ -566,6 +566,28 @@ public class DecimalFormat extends NumberFormat {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
final StringBuf format(Object number,
|
||||||
|
StringBuf toAppendTo,
|
||||||
|
FieldPosition pos) {
|
||||||
|
if (number instanceof Long || number instanceof Integer ||
|
||||||
|
number instanceof Short || number instanceof Byte ||
|
||||||
|
number instanceof AtomicInteger ||
|
||||||
|
number instanceof AtomicLong ||
|
||||||
|
(number instanceof BigInteger &&
|
||||||
|
((BigInteger) number).bitLength() < 64)) {
|
||||||
|
return format(((Number) number).longValue(), toAppendTo, pos);
|
||||||
|
} else if (number instanceof BigDecimal) {
|
||||||
|
return format((BigDecimal) number, toAppendTo, pos);
|
||||||
|
} else if (number instanceof BigInteger) {
|
||||||
|
return format((BigInteger) number, toAppendTo, pos);
|
||||||
|
} else if (number instanceof Number) {
|
||||||
|
return format(((Number) number).doubleValue(), toAppendTo, pos);
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Cannot format given Object as a Number");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Formats a double to produce a string.
|
* Formats a double to produce a string.
|
||||||
* @param number The double to format
|
* @param number The double to format
|
||||||
@ -588,6 +610,12 @@ public class DecimalFormat extends NumberFormat {
|
|||||||
@Override
|
@Override
|
||||||
public StringBuffer format(double number, StringBuffer result,
|
public StringBuffer format(double number, StringBuffer result,
|
||||||
FieldPosition fieldPosition) {
|
FieldPosition fieldPosition) {
|
||||||
|
return format(number, StringBufFactory.of(result), fieldPosition).asStringBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
StringBuf format(double number, StringBuf result,
|
||||||
|
FieldPosition fieldPosition) {
|
||||||
// If fieldPosition is a DontCareFieldPosition instance we can
|
// If fieldPosition is a DontCareFieldPosition instance we can
|
||||||
// try to go to fast-path code.
|
// try to go to fast-path code.
|
||||||
boolean tryFastPath = false;
|
boolean tryFastPath = false;
|
||||||
@ -619,8 +647,8 @@ public class DecimalFormat extends NumberFormat {
|
|||||||
* mode being set to RoundingMode.UNNECESSARY
|
* mode being set to RoundingMode.UNNECESSARY
|
||||||
* @return The formatted number string
|
* @return The formatted number string
|
||||||
*/
|
*/
|
||||||
StringBuffer format(double number, StringBuffer result,
|
StringBuf format(double number, StringBuf result,
|
||||||
FieldDelegate delegate) {
|
FieldDelegate delegate) {
|
||||||
|
|
||||||
boolean nanOrInfinity = handleNaN(number, result, delegate);
|
boolean nanOrInfinity = handleNaN(number, result, delegate);
|
||||||
if (nanOrInfinity) {
|
if (nanOrInfinity) {
|
||||||
@ -666,7 +694,7 @@ public class DecimalFormat extends NumberFormat {
|
|||||||
* @param delegate notified of locations of sub fields
|
* @param delegate notified of locations of sub fields
|
||||||
* @return true, if number is a NaN; false otherwise
|
* @return true, if number is a NaN; false otherwise
|
||||||
*/
|
*/
|
||||||
boolean handleNaN(double number, StringBuffer result,
|
boolean handleNaN(double number, StringBuf result,
|
||||||
FieldDelegate delegate) {
|
FieldDelegate delegate) {
|
||||||
if (Double.isNaN(number)
|
if (Double.isNaN(number)
|
||||||
|| (Double.isInfinite(number) && multiplier == 0)) {
|
|| (Double.isInfinite(number) && multiplier == 0)) {
|
||||||
@ -691,7 +719,7 @@ public class DecimalFormat extends NumberFormat {
|
|||||||
* @return true, if number is a {@code Double.NEGATIVE_INFINITY} or
|
* @return true, if number is a {@code Double.NEGATIVE_INFINITY} or
|
||||||
* {@code Double.POSITIVE_INFINITY}; false otherwise
|
* {@code Double.POSITIVE_INFINITY}; false otherwise
|
||||||
*/
|
*/
|
||||||
boolean handleInfinity(double number, StringBuffer result,
|
boolean handleInfinity(double number, StringBuf result,
|
||||||
FieldDelegate delegate, boolean isNegative) {
|
FieldDelegate delegate, boolean isNegative) {
|
||||||
if (Double.isInfinite(number)) {
|
if (Double.isInfinite(number)) {
|
||||||
if (isNegative) {
|
if (isNegative) {
|
||||||
@ -720,7 +748,7 @@ public class DecimalFormat extends NumberFormat {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuffer doubleSubformat(double number, StringBuffer result,
|
StringBuf doubleSubformat(double number, StringBuf result,
|
||||||
FieldDelegate delegate, boolean isNegative) {
|
FieldDelegate delegate, boolean isNegative) {
|
||||||
synchronized (digitList) {
|
synchronized (digitList) {
|
||||||
int maxIntDigits = super.getMaximumIntegerDigits();
|
int maxIntDigits = super.getMaximumIntegerDigits();
|
||||||
@ -761,6 +789,14 @@ public class DecimalFormat extends NumberFormat {
|
|||||||
fieldPosition.setBeginIndex(0);
|
fieldPosition.setBeginIndex(0);
|
||||||
fieldPosition.setEndIndex(0);
|
fieldPosition.setEndIndex(0);
|
||||||
|
|
||||||
|
return format(number, StringBufFactory.of(result), fieldPosition.getFieldDelegate()).asStringBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuf format(long number, StringBuf result,
|
||||||
|
FieldPosition fieldPosition) {
|
||||||
|
fieldPosition.setBeginIndex(0);
|
||||||
|
fieldPosition.setEndIndex(0);
|
||||||
|
|
||||||
return format(number, result, fieldPosition.getFieldDelegate());
|
return format(number, result, fieldPosition.getFieldDelegate());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -774,8 +810,8 @@ public class DecimalFormat extends NumberFormat {
|
|||||||
* mode being set to RoundingMode.UNNECESSARY
|
* mode being set to RoundingMode.UNNECESSARY
|
||||||
* @see java.text.FieldPosition
|
* @see java.text.FieldPosition
|
||||||
*/
|
*/
|
||||||
StringBuffer format(long number, StringBuffer result,
|
StringBuf format(long number, StringBuf result,
|
||||||
FieldDelegate delegate) {
|
FieldDelegate delegate) {
|
||||||
boolean isNegative = (number < 0);
|
boolean isNegative = (number < 0);
|
||||||
if (isNegative) {
|
if (isNegative) {
|
||||||
number = -number;
|
number = -number;
|
||||||
@ -849,8 +885,8 @@ public class DecimalFormat extends NumberFormat {
|
|||||||
* mode being set to RoundingMode.UNNECESSARY
|
* mode being set to RoundingMode.UNNECESSARY
|
||||||
* @see java.text.FieldPosition
|
* @see java.text.FieldPosition
|
||||||
*/
|
*/
|
||||||
private StringBuffer format(BigDecimal number, StringBuffer result,
|
private StringBuf format(BigDecimal number, StringBuf result,
|
||||||
FieldPosition fieldPosition) {
|
FieldPosition fieldPosition) {
|
||||||
fieldPosition.setBeginIndex(0);
|
fieldPosition.setBeginIndex(0);
|
||||||
fieldPosition.setEndIndex(0);
|
fieldPosition.setEndIndex(0);
|
||||||
return format(number, result, fieldPosition.getFieldDelegate());
|
return format(number, result, fieldPosition.getFieldDelegate());
|
||||||
@ -865,8 +901,8 @@ public class DecimalFormat extends NumberFormat {
|
|||||||
* mode being set to RoundingMode.UNNECESSARY
|
* mode being set to RoundingMode.UNNECESSARY
|
||||||
* @return The formatted number string
|
* @return The formatted number string
|
||||||
*/
|
*/
|
||||||
StringBuffer format(BigDecimal number, StringBuffer result,
|
StringBuf format(BigDecimal number, StringBuf result,
|
||||||
FieldDelegate delegate) {
|
FieldDelegate delegate) {
|
||||||
if (multiplier != 1) {
|
if (multiplier != 1) {
|
||||||
number = number.multiply(getBigDecimalMultiplier());
|
number = number.multiply(getBigDecimalMultiplier());
|
||||||
}
|
}
|
||||||
@ -908,8 +944,8 @@ public class DecimalFormat extends NumberFormat {
|
|||||||
* mode being set to RoundingMode.UNNECESSARY
|
* mode being set to RoundingMode.UNNECESSARY
|
||||||
* @see java.text.FieldPosition
|
* @see java.text.FieldPosition
|
||||||
*/
|
*/
|
||||||
private StringBuffer format(BigInteger number, StringBuffer result,
|
private StringBuf format(BigInteger number, StringBuf result,
|
||||||
FieldPosition fieldPosition) {
|
FieldPosition fieldPosition) {
|
||||||
fieldPosition.setBeginIndex(0);
|
fieldPosition.setBeginIndex(0);
|
||||||
fieldPosition.setEndIndex(0);
|
fieldPosition.setEndIndex(0);
|
||||||
|
|
||||||
@ -926,8 +962,8 @@ public class DecimalFormat extends NumberFormat {
|
|||||||
* mode being set to RoundingMode.UNNECESSARY
|
* mode being set to RoundingMode.UNNECESSARY
|
||||||
* @see java.text.FieldPosition
|
* @see java.text.FieldPosition
|
||||||
*/
|
*/
|
||||||
StringBuffer format(BigInteger number, StringBuffer result,
|
StringBuf format(BigInteger number, StringBuf result,
|
||||||
FieldDelegate delegate, boolean formatLong) {
|
FieldDelegate delegate, boolean formatLong) {
|
||||||
if (multiplier != 1) {
|
if (multiplier != 1) {
|
||||||
number = number.multiply(getBigIntegerMultiplier());
|
number = number.multiply(getBigIntegerMultiplier());
|
||||||
}
|
}
|
||||||
@ -986,7 +1022,7 @@ public class DecimalFormat extends NumberFormat {
|
|||||||
public AttributedCharacterIterator formatToCharacterIterator(Object obj) {
|
public AttributedCharacterIterator formatToCharacterIterator(Object obj) {
|
||||||
CharacterIteratorFieldDelegate delegate =
|
CharacterIteratorFieldDelegate delegate =
|
||||||
new CharacterIteratorFieldDelegate();
|
new CharacterIteratorFieldDelegate();
|
||||||
StringBuffer sb = new StringBuffer();
|
StringBuf sb = StringBufFactory.of();
|
||||||
|
|
||||||
if (obj instanceof Double || obj instanceof Float) {
|
if (obj instanceof Double || obj instanceof Float) {
|
||||||
format(((Number)obj).doubleValue(), sb, delegate);
|
format(((Number)obj).doubleValue(), sb, delegate);
|
||||||
@ -1779,7 +1815,7 @@ public class DecimalFormat extends NumberFormat {
|
|||||||
* Complete the formatting of a finite number. On entry, the digitList must
|
* Complete the formatting of a finite number. On entry, the digitList must
|
||||||
* be filled in with the correct digits.
|
* be filled in with the correct digits.
|
||||||
*/
|
*/
|
||||||
private StringBuffer subformat(StringBuffer result, FieldDelegate delegate,
|
private StringBuf subformat(StringBuf result, FieldDelegate delegate,
|
||||||
boolean isNegative, boolean isInteger,
|
boolean isNegative, boolean isInteger,
|
||||||
int maxIntDigits, int minIntDigits,
|
int maxIntDigits, int minIntDigits,
|
||||||
int maxFraDigits, int minFraDigits) {
|
int maxFraDigits, int minFraDigits) {
|
||||||
@ -1821,7 +1857,7 @@ public class DecimalFormat extends NumberFormat {
|
|||||||
* @param maxFraDigits maximum fraction digits
|
* @param maxFraDigits maximum fraction digits
|
||||||
* @param minFraDigits minimum fraction digits
|
* @param minFraDigits minimum fraction digits
|
||||||
*/
|
*/
|
||||||
void subformatNumber(StringBuffer result, FieldDelegate delegate,
|
void subformatNumber(StringBuf result, FieldDelegate delegate,
|
||||||
boolean isNegative, boolean isInteger,
|
boolean isNegative, boolean isInteger,
|
||||||
int maxIntDigits, int minIntDigits,
|
int maxIntDigits, int minIntDigits,
|
||||||
int maxFraDigits, int minFraDigits) {
|
int maxFraDigits, int minFraDigits) {
|
||||||
@ -2108,7 +2144,7 @@ public class DecimalFormat extends NumberFormat {
|
|||||||
* <p>
|
* <p>
|
||||||
* This is used by {@code subformat} to add the prefix/suffix.
|
* This is used by {@code subformat} to add the prefix/suffix.
|
||||||
*/
|
*/
|
||||||
private void append(StringBuffer result, String string,
|
private void append(StringBuf result, String string,
|
||||||
FieldDelegate delegate,
|
FieldDelegate delegate,
|
||||||
FieldPosition[] positions,
|
FieldPosition[] positions,
|
||||||
Format.Field signAttribute) {
|
Format.Field signAttribute) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -36,10 +36,10 @@ class DontCareFieldPosition extends FieldPosition {
|
|||||||
|
|
||||||
private final Format.FieldDelegate noDelegate = new Format.FieldDelegate() {
|
private final Format.FieldDelegate noDelegate = new Format.FieldDelegate() {
|
||||||
public void formatted(Format.Field attr, Object value, int start,
|
public void formatted(Format.Field attr, Object value, int start,
|
||||||
int end, StringBuffer buffer) {
|
int end, Format.StringBuf buffer) {
|
||||||
}
|
}
|
||||||
public void formatted(int fieldID, Format.Field attr, Object value,
|
public void formatted(int fieldID, Format.Field attr, Object value,
|
||||||
int start, int end, StringBuffer buffer) {
|
int start, int end, Format.StringBuf buffer) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1996, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -290,7 +290,7 @@ public class FieldPosition {
|
|||||||
private boolean encounteredField;
|
private boolean encounteredField;
|
||||||
|
|
||||||
public void formatted(Format.Field attr, Object value, int start,
|
public void formatted(Format.Field attr, Object value, int start,
|
||||||
int end, StringBuffer buffer) {
|
int end, Format.StringBuf buffer) {
|
||||||
if (!encounteredField && matchesField(attr)) {
|
if (!encounteredField && matchesField(attr)) {
|
||||||
setBeginIndex(start);
|
setBeginIndex(start);
|
||||||
setEndIndex(end);
|
setEndIndex(end);
|
||||||
@ -299,7 +299,7 @@ public class FieldPosition {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void formatted(int fieldID, Format.Field attr, Object value,
|
public void formatted(int fieldID, Format.Field attr, Object value,
|
||||||
int start, int end, StringBuffer buffer) {
|
int start, int end, Format.StringBuf buffer) {
|
||||||
if (!encounteredField && matchesField(attr, fieldID)) {
|
if (!encounteredField && matchesField(attr, fieldID)) {
|
||||||
setBeginIndex(start);
|
setBeginIndex(start);
|
||||||
setEndIndex(end);
|
setEndIndex(end);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1996, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -148,7 +148,8 @@ public abstract class Format implements Serializable, Cloneable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Formats an object to produce a string. This is equivalent to
|
* Formats an object to produce a string.
|
||||||
|
* This method returns a string that would be equal to the string returned by
|
||||||
* <blockquote>
|
* <blockquote>
|
||||||
* {@link #format(Object, StringBuffer, FieldPosition) format}<code>(obj,
|
* {@link #format(Object, StringBuffer, FieldPosition) format}<code>(obj,
|
||||||
* new StringBuffer(), new FieldPosition(0)).toString();</code>
|
* new StringBuffer(), new FieldPosition(0)).toString();</code>
|
||||||
@ -160,7 +161,11 @@ public abstract class Format implements Serializable, Cloneable {
|
|||||||
* object
|
* object
|
||||||
*/
|
*/
|
||||||
public final String format (Object obj) {
|
public final String format (Object obj) {
|
||||||
return format(obj, new StringBuffer(), new FieldPosition(0)).toString();
|
if ("java.text".equals(getClass().getPackageName())) {
|
||||||
|
return format(obj, StringBufFactory.of(), new FieldPosition(0)).toString();
|
||||||
|
} else {
|
||||||
|
return format(obj, new StringBuffer(), new FieldPosition(0)).toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -185,6 +190,12 @@ public abstract class Format implements Serializable, Cloneable {
|
|||||||
StringBuffer toAppendTo,
|
StringBuffer toAppendTo,
|
||||||
FieldPosition pos);
|
FieldPosition pos);
|
||||||
|
|
||||||
|
StringBuf format(Object obj,
|
||||||
|
StringBuf toAppendTo,
|
||||||
|
FieldPosition pos) {
|
||||||
|
throw new UnsupportedOperationException("Subclasses should override this method");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Formats an Object producing an {@code AttributedCharacterIterator}.
|
* Formats an Object producing an {@code AttributedCharacterIterator}.
|
||||||
* You can use the returned {@code AttributedCharacterIterator}
|
* You can use the returned {@code AttributedCharacterIterator}
|
||||||
@ -394,7 +405,7 @@ public abstract class Format implements Serializable, Cloneable {
|
|||||||
* NOT modify it.
|
* NOT modify it.
|
||||||
*/
|
*/
|
||||||
public void formatted(Format.Field attr, Object value, int start,
|
public void formatted(Format.Field attr, Object value, int start,
|
||||||
int end, StringBuffer buffer);
|
int end, StringBuf buffer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notified when a particular region of the String is formatted.
|
* Notified when a particular region of the String is formatted.
|
||||||
@ -408,6 +419,38 @@ public abstract class Format implements Serializable, Cloneable {
|
|||||||
* NOT modify it.
|
* NOT modify it.
|
||||||
*/
|
*/
|
||||||
public void formatted(int fieldID, Format.Field attr, Object value,
|
public void formatted(int fieldID, Format.Field attr, Object value,
|
||||||
int start, int end, StringBuffer buffer);
|
int start, int end, StringBuf buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StringBuf is the minimal common interface of {@code StringBuffer} and {@code StringBuilder}.
|
||||||
|
* It is used by the various {@code Format} implementations as the internal string buffer.
|
||||||
|
*/
|
||||||
|
sealed interface StringBuf
|
||||||
|
permits StringBufFactory.StringBufferImpl, StringBufFactory.StringBuilderImpl {
|
||||||
|
|
||||||
|
int length();
|
||||||
|
|
||||||
|
String substring(int start, int end);
|
||||||
|
|
||||||
|
String substring(int start);
|
||||||
|
|
||||||
|
StringBuf append(char c);
|
||||||
|
|
||||||
|
StringBuf append(String str);
|
||||||
|
|
||||||
|
StringBuf append(int i);
|
||||||
|
|
||||||
|
StringBuf append(char[] str, int offset, int len);
|
||||||
|
|
||||||
|
StringBuf append(CharSequence s, int start, int end);
|
||||||
|
|
||||||
|
StringBuf append(StringBuffer sb);
|
||||||
|
|
||||||
|
boolean isProxyStringBuilder();
|
||||||
|
|
||||||
|
StringBuffer asStringBuffer();
|
||||||
|
|
||||||
|
StringBuilder asStringBuilder();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -356,7 +356,7 @@ public final class ListFormat extends Format {
|
|||||||
public String format(List<String> input) {
|
public String format(List<String> input) {
|
||||||
Objects.requireNonNull(input);
|
Objects.requireNonNull(input);
|
||||||
|
|
||||||
return format(input, new StringBuffer(),
|
return format(input, StringBufFactory.of(),
|
||||||
DontCareFieldPosition.INSTANCE).toString();
|
DontCareFieldPosition.INSTANCE).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -381,6 +381,18 @@ public final class ListFormat extends Format {
|
|||||||
Objects.requireNonNull(obj);
|
Objects.requireNonNull(obj);
|
||||||
Objects.requireNonNull(toAppendTo);
|
Objects.requireNonNull(toAppendTo);
|
||||||
|
|
||||||
|
return format(obj, StringBufFactory.of(toAppendTo)).asStringBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
StringBuf format(Object obj, StringBuf toAppendTo, FieldPosition pos) {
|
||||||
|
Objects.requireNonNull(obj);
|
||||||
|
Objects.requireNonNull(toAppendTo);
|
||||||
|
|
||||||
|
return format(obj, toAppendTo);
|
||||||
|
}
|
||||||
|
|
||||||
|
private StringBuf format(Object obj, StringBuf toAppendTo) {
|
||||||
if (obj instanceof Object[] objs) {
|
if (obj instanceof Object[] objs) {
|
||||||
return generateMessageFormat(objs).format(objs, toAppendTo, DontCareFieldPosition.INSTANCE);
|
return generateMessageFormat(objs).format(objs, toAppendTo, DontCareFieldPosition.INSTANCE);
|
||||||
} else if (obj instanceof List<?> objs) {
|
} else if (obj instanceof List<?> objs) {
|
||||||
|
@ -1027,12 +1027,13 @@ public class MessageFormat extends Format {
|
|||||||
public final StringBuffer format(Object[] arguments, StringBuffer result,
|
public final StringBuffer format(Object[] arguments, StringBuffer result,
|
||||||
FieldPosition pos)
|
FieldPosition pos)
|
||||||
{
|
{
|
||||||
return subformat(arguments, result, pos, null);
|
return subformat(arguments, StringBufFactory.of(result), pos, null).asStringBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a MessageFormat with the given pattern and uses it
|
* Creates a MessageFormat with the given pattern and uses it
|
||||||
* to format the given arguments. This is equivalent to
|
* to format the given arguments.
|
||||||
|
* This method returns a string that would be equal to the string returned by
|
||||||
* <blockquote>
|
* <blockquote>
|
||||||
* <code>(new {@link #MessageFormat(String) MessageFormat}(pattern)).{@link #format(java.lang.Object[], java.lang.StringBuffer, java.text.FieldPosition) format}(arguments, new StringBuffer(), null).toString()</code>
|
* <code>(new {@link #MessageFormat(String) MessageFormat}(pattern)).{@link #format(java.lang.Object[], java.lang.StringBuffer, java.text.FieldPosition) format}(arguments, new StringBuffer(), null).toString()</code>
|
||||||
* </blockquote>
|
* </blockquote>
|
||||||
@ -1076,6 +1077,12 @@ public class MessageFormat extends Format {
|
|||||||
public final StringBuffer format(Object arguments, StringBuffer result,
|
public final StringBuffer format(Object arguments, StringBuffer result,
|
||||||
FieldPosition pos)
|
FieldPosition pos)
|
||||||
{
|
{
|
||||||
|
return subformat((Object[]) arguments, StringBufFactory.of(result), pos, null).asStringBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
final StringBuf format(Object arguments, StringBuf result,
|
||||||
|
FieldPosition pos) {
|
||||||
return subformat((Object[]) arguments, result, pos, null);
|
return subformat((Object[]) arguments, result, pos, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1116,7 +1123,7 @@ public class MessageFormat extends Format {
|
|||||||
*/
|
*/
|
||||||
public AttributedCharacterIterator formatToCharacterIterator(Object arguments) {
|
public AttributedCharacterIterator formatToCharacterIterator(Object arguments) {
|
||||||
Objects.requireNonNull(arguments, "arguments must not be null");
|
Objects.requireNonNull(arguments, "arguments must not be null");
|
||||||
StringBuffer result = new StringBuffer();
|
StringBuf result = StringBufFactory.of();
|
||||||
ArrayList<AttributedCharacterIterator> iterators = new ArrayList<>();
|
ArrayList<AttributedCharacterIterator> iterators = new ArrayList<>();
|
||||||
|
|
||||||
subformat((Object[]) arguments, result, null, iterators);
|
subformat((Object[]) arguments, result, null, iterators);
|
||||||
@ -1472,7 +1479,7 @@ public class MessageFormat extends Format {
|
|||||||
* {@code arguments} array is not of the type
|
* {@code arguments} array is not of the type
|
||||||
* expected by the format element(s) that use it.
|
* expected by the format element(s) that use it.
|
||||||
*/
|
*/
|
||||||
private StringBuffer subformat(Object[] arguments, StringBuffer result,
|
private StringBuf subformat(Object[] arguments, StringBuf result,
|
||||||
FieldPosition fp, List<AttributedCharacterIterator> characterIterators) {
|
FieldPosition fp, List<AttributedCharacterIterator> characterIterators) {
|
||||||
// note: this implementation assumes a fast substring & index.
|
// note: this implementation assumes a fast substring & index.
|
||||||
// if this is not true, would be better to append chars one by one.
|
// if this is not true, would be better to append chars one by one.
|
||||||
@ -1582,9 +1589,9 @@ public class MessageFormat extends Format {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience method to append all the characters in
|
* Convenience method to append all the characters in
|
||||||
* {@code iterator} to the StringBuffer {@code result}.
|
* {@code iterator} to the StringBuf {@code result}.
|
||||||
*/
|
*/
|
||||||
private void append(StringBuffer result, CharacterIterator iterator) {
|
private void append(StringBuf result, CharacterIterator iterator) {
|
||||||
if (iterator.first() != CharacterIterator.DONE) {
|
if (iterator.first() != CharacterIterator.DONE) {
|
||||||
char aChar;
|
char aChar;
|
||||||
|
|
||||||
|
@ -315,6 +315,23 @@ public abstract class NumberFormat extends Format {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
StringBuf format(Object number,
|
||||||
|
StringBuf toAppendTo,
|
||||||
|
FieldPosition pos) {
|
||||||
|
if (number instanceof Long || number instanceof Integer ||
|
||||||
|
number instanceof Short || number instanceof Byte ||
|
||||||
|
number instanceof AtomicInteger || number instanceof AtomicLong ||
|
||||||
|
(number instanceof BigInteger &&
|
||||||
|
((BigInteger) number).bitLength() < 64)) {
|
||||||
|
return format(((Number) number).longValue(), toAppendTo, pos);
|
||||||
|
} else if (number instanceof Number) {
|
||||||
|
return format(((Number) number).doubleValue(), toAppendTo, pos);
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Cannot format given Object as a Number");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc Format}
|
* {@inheritDoc Format}
|
||||||
*
|
*
|
||||||
@ -347,8 +364,13 @@ public abstract class NumberFormat extends Format {
|
|||||||
if (result != null)
|
if (result != null)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
return format(number, new StringBuffer(),
|
if ("java.text".equals(getClass().getPackageName())) {
|
||||||
DontCareFieldPosition.INSTANCE).toString();
|
return format(number, StringBufFactory.of(),
|
||||||
|
DontCareFieldPosition.INSTANCE).toString();
|
||||||
|
} else {
|
||||||
|
return format(number, new StringBuffer(),
|
||||||
|
DontCareFieldPosition.INSTANCE).toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -367,8 +389,13 @@ public abstract class NumberFormat extends Format {
|
|||||||
* @see java.text.Format#format
|
* @see java.text.Format#format
|
||||||
*/
|
*/
|
||||||
public final String format(long number) {
|
public final String format(long number) {
|
||||||
return format(number, new StringBuffer(),
|
if ("java.text".equals(getClass().getPackageName())) {
|
||||||
DontCareFieldPosition.INSTANCE).toString();
|
return format(number, StringBufFactory.of(),
|
||||||
|
DontCareFieldPosition.INSTANCE).toString();
|
||||||
|
} else {
|
||||||
|
return format(number, new StringBuffer(),
|
||||||
|
DontCareFieldPosition.INSTANCE).toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -394,6 +421,12 @@ public abstract class NumberFormat extends Format {
|
|||||||
StringBuffer toAppendTo,
|
StringBuffer toAppendTo,
|
||||||
FieldPosition pos);
|
FieldPosition pos);
|
||||||
|
|
||||||
|
StringBuf format(double number,
|
||||||
|
StringBuf toAppendTo,
|
||||||
|
FieldPosition pos) {
|
||||||
|
throw new UnsupportedOperationException("Subclasses should override this method");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specialization of format.
|
* Specialization of format.
|
||||||
*
|
*
|
||||||
@ -417,6 +450,12 @@ public abstract class NumberFormat extends Format {
|
|||||||
StringBuffer toAppendTo,
|
StringBuffer toAppendTo,
|
||||||
FieldPosition pos);
|
FieldPosition pos);
|
||||||
|
|
||||||
|
StringBuf format(long number,
|
||||||
|
StringBuf toAppendTo,
|
||||||
|
FieldPosition pos) {
|
||||||
|
throw new UnsupportedOperationException("Subclasses should override this method");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses text from the beginning of the given string to produce a {@code Number}.
|
* Parses text from the beginning of the given string to produce a {@code Number}.
|
||||||
* <p>
|
* <p>
|
||||||
|
@ -968,11 +968,18 @@ public class SimpleDateFormat extends DateFormat {
|
|||||||
FieldPosition pos)
|
FieldPosition pos)
|
||||||
{
|
{
|
||||||
pos.beginIndex = pos.endIndex = 0;
|
pos.beginIndex = pos.endIndex = 0;
|
||||||
|
return format(date, StringBufFactory.of(toAppendTo), pos.getFieldDelegate()).asStringBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
final StringBuf format(Date date, StringBuf toAppendTo,
|
||||||
|
FieldPosition pos) {
|
||||||
|
pos.beginIndex = pos.endIndex = 0;
|
||||||
return format(date, toAppendTo, pos.getFieldDelegate());
|
return format(date, toAppendTo, pos.getFieldDelegate());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called from Format after creating a FieldDelegate
|
// Called from Format after creating a FieldDelegate
|
||||||
private StringBuffer format(Date date, StringBuffer toAppendTo,
|
private StringBuf format(Date date, StringBuf toAppendTo,
|
||||||
FieldDelegate delegate) {
|
FieldDelegate delegate) {
|
||||||
// Convert input date to time field list
|
// Convert input date to time field list
|
||||||
calendar.setTime(date);
|
calendar.setTime(date);
|
||||||
@ -1024,7 +1031,7 @@ public class SimpleDateFormat extends DateFormat {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public AttributedCharacterIterator formatToCharacterIterator(Object obj) {
|
public AttributedCharacterIterator formatToCharacterIterator(Object obj) {
|
||||||
StringBuffer sb = new StringBuffer();
|
StringBuf sb = StringBufFactory.of();
|
||||||
CharacterIteratorFieldDelegate delegate = new
|
CharacterIteratorFieldDelegate delegate = new
|
||||||
CharacterIteratorFieldDelegate();
|
CharacterIteratorFieldDelegate();
|
||||||
|
|
||||||
@ -1130,7 +1137,7 @@ public class SimpleDateFormat extends DateFormat {
|
|||||||
* Private member function that does the real date/time formatting.
|
* Private member function that does the real date/time formatting.
|
||||||
*/
|
*/
|
||||||
private void subFormat(int patternCharIndex, int count,
|
private void subFormat(int patternCharIndex, int count,
|
||||||
FieldDelegate delegate, StringBuffer buffer,
|
FieldDelegate delegate, StringBuf buffer,
|
||||||
boolean useDateFormatSymbols)
|
boolean useDateFormatSymbols)
|
||||||
{
|
{
|
||||||
int maxIntCount = Integer.MAX_VALUE;
|
int maxIntCount = Integer.MAX_VALUE;
|
||||||
@ -1320,7 +1327,11 @@ public class SimpleDateFormat extends DateFormat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int num = (value / 60) * 100 + (value % 60);
|
int num = (value / 60) * 100 + (value % 60);
|
||||||
CalendarUtils.sprintf0d(buffer, num, width);
|
if (buffer.isProxyStringBuilder()) {
|
||||||
|
CalendarUtils.sprintf0d(buffer.asStringBuilder(), num, width);
|
||||||
|
} else {
|
||||||
|
CalendarUtils.sprintf0d(buffer.asStringBuffer(), num, width);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PATTERN_ISO_ZONE: // 'X'
|
case PATTERN_ISO_ZONE: // 'X'
|
||||||
@ -1340,7 +1351,11 @@ public class SimpleDateFormat extends DateFormat {
|
|||||||
value = -value;
|
value = -value;
|
||||||
}
|
}
|
||||||
|
|
||||||
CalendarUtils.sprintf0d(buffer, value / 60, 2);
|
if (buffer.isProxyStringBuilder()) {
|
||||||
|
CalendarUtils.sprintf0d(buffer.asStringBuilder(), value / 60, 2);
|
||||||
|
} else {
|
||||||
|
CalendarUtils.sprintf0d(buffer.asStringBuffer(), value / 60, 2);
|
||||||
|
}
|
||||||
if (count == 1) {
|
if (count == 1) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1348,7 +1363,11 @@ public class SimpleDateFormat extends DateFormat {
|
|||||||
if (count == 3) {
|
if (count == 3) {
|
||||||
buffer.append(':');
|
buffer.append(':');
|
||||||
}
|
}
|
||||||
CalendarUtils.sprintf0d(buffer, value % 60, 2);
|
if (buffer.isProxyStringBuilder()) {
|
||||||
|
CalendarUtils.sprintf0d(buffer.asStringBuilder(), value % 60, 2);
|
||||||
|
} else {
|
||||||
|
CalendarUtils.sprintf0d(buffer.asStringBuffer(), value % 60, 2);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -1382,7 +1401,7 @@ public class SimpleDateFormat extends DateFormat {
|
|||||||
/**
|
/**
|
||||||
* Formats a number with the specified minimum and maximum number of digits.
|
* Formats a number with the specified minimum and maximum number of digits.
|
||||||
*/
|
*/
|
||||||
private void zeroPaddingNumber(int value, int minDigits, int maxDigits, StringBuffer buffer)
|
private void zeroPaddingNumber(int value, int minDigits, int maxDigits, StringBuf buffer)
|
||||||
{
|
{
|
||||||
// Optimization for 1, 2 and 4 digit numbers. This should
|
// Optimization for 1, 2 and 4 digit numbers. This should
|
||||||
// cover most cases of formatting date/time related items.
|
// cover most cases of formatting date/time related items.
|
||||||
@ -1425,7 +1444,17 @@ public class SimpleDateFormat extends DateFormat {
|
|||||||
|
|
||||||
numberFormat.setMinimumIntegerDigits(minDigits);
|
numberFormat.setMinimumIntegerDigits(minDigits);
|
||||||
numberFormat.setMaximumIntegerDigits(maxDigits);
|
numberFormat.setMaximumIntegerDigits(maxDigits);
|
||||||
numberFormat.format((long)value, buffer, DontCareFieldPosition.INSTANCE);
|
if (buffer.isProxyStringBuilder()) {
|
||||||
|
//User can set numberFormat with a user-defined NumberFormat which
|
||||||
|
//not override format(long, StringBuf, FieldPosition).
|
||||||
|
if ("java.text".equals(numberFormat.getClass().getPackageName())) {
|
||||||
|
numberFormat.format((long) value, buffer, DontCareFieldPosition.INSTANCE);
|
||||||
|
} else {
|
||||||
|
buffer.append(numberFormat.format((long) value, new StringBuffer(), DontCareFieldPosition.INSTANCE));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
numberFormat.format((long) value, buffer.asStringBuffer(), DontCareFieldPosition.INSTANCE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2565,5 +2594,4 @@ public class SimpleDateFormat extends DateFormat {
|
|||||||
originalNumberFormat = numberFormat;
|
originalNumberFormat = numberFormat;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
216
src/java.base/share/classes/java/text/StringBufFactory.java
Normal file
216
src/java.base/share/classes/java/text/StringBufFactory.java
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024, Alibaba Group Holding Limited. All Rights Reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package java.text;
|
||||||
|
|
||||||
|
import java.text.Format.StringBuf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code StringBufFactory} creates implementations of {@code Format.StringBuf},
|
||||||
|
* which is an interface with the minimum overlap required to support {@code StringBuffer}
|
||||||
|
* and {@code StringBuilder} in {@code Format}. This allows for {@code StringBuilder} to be used
|
||||||
|
* in place of {@code StringBuffer} to provide performance benefits for JDK internal
|
||||||
|
* {@code Format} subclasses.
|
||||||
|
*/
|
||||||
|
final class StringBufFactory {
|
||||||
|
|
||||||
|
private StringBufFactory() {
|
||||||
|
}
|
||||||
|
|
||||||
|
static StringBuf of(StringBuffer sb) {
|
||||||
|
return new StringBufferImpl(sb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static StringBuf of(StringBuilder sb) {
|
||||||
|
return new StringBuilderImpl(sb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static StringBuf of() {
|
||||||
|
return new StringBuilderImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
final static class StringBufferImpl implements StringBuf {
|
||||||
|
private final StringBuffer sb;
|
||||||
|
|
||||||
|
StringBufferImpl(StringBuffer sb) {
|
||||||
|
this.sb = sb;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int length() {
|
||||||
|
return sb.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String substring(int start, int end) {
|
||||||
|
return sb.substring(start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String substring(int start) {
|
||||||
|
return sb.substring(start);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StringBuf append(char c) {
|
||||||
|
sb.append(c);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StringBuf append(String str) {
|
||||||
|
sb.append(str);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StringBuf append(int i) {
|
||||||
|
sb.append(i);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StringBuf append(char[] str, int offset, int len) {
|
||||||
|
sb.append(str, offset, len);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StringBuf append(CharSequence s, int start, int end) {
|
||||||
|
sb.append(s, start, end);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StringBuf append(StringBuffer asb) {
|
||||||
|
sb.append(asb);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isProxyStringBuilder() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StringBuffer asStringBuffer() {
|
||||||
|
return sb;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StringBuilder asStringBuilder() {
|
||||||
|
throw new AssertionError("Can't cast StringBuffer to StringBuilder");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final static class StringBuilderImpl implements StringBuf {
|
||||||
|
private final StringBuilder sb;
|
||||||
|
|
||||||
|
StringBuilderImpl(StringBuilder sb) {
|
||||||
|
this.sb = sb;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilderImpl() {
|
||||||
|
this.sb = new StringBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int length() {
|
||||||
|
return sb.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String substring(int start, int end) {
|
||||||
|
return sb.substring(start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String substring(int start) {
|
||||||
|
return sb.substring(start);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StringBuf append(char c) {
|
||||||
|
sb.append(c);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StringBuf append(String str) {
|
||||||
|
sb.append(str);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StringBuf append(int i) {
|
||||||
|
sb.append(i);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StringBuf append(char[] str, int offset, int len) {
|
||||||
|
sb.append(str, offset, len);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StringBuf append(CharSequence s, int start, int end) {
|
||||||
|
sb.append(s, start, end);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StringBuf append(StringBuffer asb) {
|
||||||
|
sb.append(asb);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isProxyStringBuilder() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StringBuffer asStringBuffer() {
|
||||||
|
throw new AssertionError("Can't cast StringBuilder to StringBuffer");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StringBuilder asStringBuilder() {
|
||||||
|
return sb;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024, Alibaba Group Holding Limited. All Rights Reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.openjdk.bench.java.text;
|
||||||
|
|
||||||
|
import org.openjdk.jmh.annotations.Benchmark;
|
||||||
|
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||||
|
import org.openjdk.jmh.annotations.Fork;
|
||||||
|
import org.openjdk.jmh.annotations.Measurement;
|
||||||
|
import org.openjdk.jmh.annotations.Mode;
|
||||||
|
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||||
|
import org.openjdk.jmh.annotations.Scope;
|
||||||
|
import org.openjdk.jmh.annotations.Setup;
|
||||||
|
import org.openjdk.jmh.annotations.State;
|
||||||
|
import org.openjdk.jmh.annotations.Warmup;
|
||||||
|
import org.openjdk.jmh.runner.Runner;
|
||||||
|
import org.openjdk.jmh.runner.options.Options;
|
||||||
|
import org.openjdk.jmh.runner.options.OptionsBuilder;
|
||||||
|
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@BenchmarkMode(Mode.Throughput)
|
||||||
|
@OutputTimeUnit(TimeUnit.MILLISECONDS)
|
||||||
|
@Warmup(iterations = 5, time = 1)
|
||||||
|
@Measurement(iterations = 5, time = 1)
|
||||||
|
@Fork(3)
|
||||||
|
@State(Scope.Benchmark)
|
||||||
|
public class DateFormatterBench {
|
||||||
|
|
||||||
|
private Date date;
|
||||||
|
|
||||||
|
private Object objDate;
|
||||||
|
|
||||||
|
@Setup
|
||||||
|
public void setup() {
|
||||||
|
date = new Date();
|
||||||
|
objDate = new Date();
|
||||||
|
}
|
||||||
|
|
||||||
|
private DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.FULL, Locale.ENGLISH);
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public String testFormatDate() {
|
||||||
|
return dateFormat.format(date);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public String testFormatObject() {
|
||||||
|
return dateFormat.format(objDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String... args) throws Exception {
|
||||||
|
Options opts = new OptionsBuilder().include(DateFormatterBench.class.getSimpleName()).shouldDoGC(true).build();
|
||||||
|
new Runner(opts).run();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024, Alibaba Group Holding Limited. All Rights Reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
package org.openjdk.bench.java.text;
|
||||||
|
|
||||||
|
import org.openjdk.jmh.annotations.Benchmark;
|
||||||
|
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||||
|
import org.openjdk.jmh.annotations.Fork;
|
||||||
|
import org.openjdk.jmh.annotations.Measurement;
|
||||||
|
import org.openjdk.jmh.annotations.Mode;
|
||||||
|
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||||
|
import org.openjdk.jmh.annotations.Scope;
|
||||||
|
import org.openjdk.jmh.annotations.Setup;
|
||||||
|
import org.openjdk.jmh.annotations.State;
|
||||||
|
import org.openjdk.jmh.annotations.Warmup;
|
||||||
|
import org.openjdk.jmh.runner.Runner;
|
||||||
|
import org.openjdk.jmh.runner.options.Options;
|
||||||
|
import org.openjdk.jmh.runner.options.OptionsBuilder;
|
||||||
|
|
||||||
|
import java.text.ListFormat;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@BenchmarkMode(Mode.Throughput)
|
||||||
|
@OutputTimeUnit(TimeUnit.MILLISECONDS)
|
||||||
|
@Warmup(iterations = 5, time = 1)
|
||||||
|
@Measurement(iterations = 5, time = 1)
|
||||||
|
@Fork(3)
|
||||||
|
@State(Scope.Benchmark)
|
||||||
|
public class ListFormatterBench {
|
||||||
|
|
||||||
|
private List<String> data;
|
||||||
|
|
||||||
|
@Setup
|
||||||
|
public void setup() {
|
||||||
|
data = List.of("foo", "bar", "baz", "qux", "quux", "quuz");
|
||||||
|
}
|
||||||
|
|
||||||
|
private ListFormat listFormat = ListFormat.getInstance();
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public String testListFormat() {
|
||||||
|
return listFormat.format(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String... args) throws Exception {
|
||||||
|
Options opts = new OptionsBuilder().include(ListFormatterBench.class.getSimpleName()).shouldDoGC(true).build();
|
||||||
|
new Runner(opts).run();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024, Alibaba Group Holding Limited. All Rights Reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
package org.openjdk.bench.java.text;
|
||||||
|
|
||||||
|
import org.openjdk.jmh.annotations.Benchmark;
|
||||||
|
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||||
|
import org.openjdk.jmh.annotations.Fork;
|
||||||
|
import org.openjdk.jmh.annotations.Measurement;
|
||||||
|
import org.openjdk.jmh.annotations.Mode;
|
||||||
|
import org.openjdk.jmh.annotations.OperationsPerInvocation;
|
||||||
|
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||||
|
import org.openjdk.jmh.annotations.Scope;
|
||||||
|
import org.openjdk.jmh.annotations.Setup;
|
||||||
|
import org.openjdk.jmh.annotations.State;
|
||||||
|
import org.openjdk.jmh.annotations.Warmup;
|
||||||
|
import org.openjdk.jmh.infra.Blackhole;
|
||||||
|
import org.openjdk.jmh.runner.Runner;
|
||||||
|
import org.openjdk.jmh.runner.options.Options;
|
||||||
|
import org.openjdk.jmh.runner.options.OptionsBuilder;
|
||||||
|
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@BenchmarkMode(Mode.Throughput)
|
||||||
|
@OutputTimeUnit(TimeUnit.MILLISECONDS)
|
||||||
|
@Warmup(iterations = 5, time = 1)
|
||||||
|
@Measurement(iterations = 5, time = 1)
|
||||||
|
@Fork(3)
|
||||||
|
@State(Scope.Benchmark)
|
||||||
|
public class MessageFormatterBench {
|
||||||
|
|
||||||
|
private Object[][] values;
|
||||||
|
|
||||||
|
@Setup
|
||||||
|
public void setup() {
|
||||||
|
values = new Object[][]{
|
||||||
|
new Object[]{Integer.valueOf(13), "MyDisk1"},
|
||||||
|
new Object[]{Float.valueOf(25.6f), "MyDisk2"},
|
||||||
|
new Object[]{Double.valueOf(123.89), "MyDisk3"},
|
||||||
|
new Object[]{Long.valueOf(1234567), "MyDisk4"},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private MessageFormat messageFormat = new MessageFormat("There is {0} GB of free space on the {1}.", Locale.ENGLISH);
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
@OperationsPerInvocation(4)
|
||||||
|
public void testMessageFormat(final Blackhole bh) {
|
||||||
|
for (Object[] value : values) {
|
||||||
|
bh.consume(messageFormat.format(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String... args) throws Exception {
|
||||||
|
Options opts = new OptionsBuilder().include(MessageFormatterBench.class.getSimpleName()).shouldDoGC(true).build();
|
||||||
|
new Runner(opts).run();
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user