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.
|
||||
*
|
||||
* 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,
|
||||
StringBuffer buffer) {
|
||||
Format.StringBuf buffer) {
|
||||
if (start != end) {
|
||||
if (start < size) {
|
||||
// Adjust attributes of existing runs
|
||||
@ -93,7 +93,7 @@ class CharacterIteratorFieldDelegate implements Format.FieldDelegate {
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -514,6 +514,12 @@ public class ChoiceFormat extends NumberFormat {
|
||||
@Override
|
||||
public StringBuffer format(long number, StringBuffer toAppendTo,
|
||||
FieldPosition 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
|
||||
public StringBuffer format(double number, StringBuffer toAppendTo,
|
||||
FieldPosition status) {
|
||||
return format(number, StringBufFactory.of(toAppendTo), status).asStringBuffer();
|
||||
}
|
||||
|
||||
@Override
|
||||
StringBuf format(double number, StringBuf toAppendTo,
|
||||
FieldPosition status) {
|
||||
// find the number
|
||||
int i;
|
||||
for (i = 0; i < choiceLimits.length; ++i) {
|
||||
|
@ -544,6 +544,35 @@ public final class CompactNumberFormat extends NumberFormat {
|
||||
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) {
|
||||
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
|
||||
@ -591,12 +620,21 @@ public final class CompactNumberFormat extends NumberFormat {
|
||||
public StringBuffer format(double number, StringBuffer result,
|
||||
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.setEndIndex(0);
|
||||
return format(number, result, fieldPosition.getFieldDelegate());
|
||||
}
|
||||
|
||||
private StringBuffer format(double number, StringBuffer result,
|
||||
private StringBuf format(double number, StringBuf result,
|
||||
FieldDelegate 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,
|
||||
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.setEndIndex(0);
|
||||
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);
|
||||
if (isNegative) {
|
||||
number = -number;
|
||||
@ -757,14 +804,14 @@ public final class CompactNumberFormat extends NumberFormat {
|
||||
* of the prefix and the suffix fields can be
|
||||
* obtained using {@link NumberFormat.Field#PREFIX}
|
||||
* 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
|
||||
* mode being set to {@code RoundingMode.UNNECESSARY}
|
||||
* @throws NullPointerException if any of the given parameter
|
||||
* is {@code null}
|
||||
* @see FieldPosition
|
||||
*/
|
||||
private StringBuffer format(BigDecimal number, StringBuffer result,
|
||||
private StringBuf format(BigDecimal number, StringBuf result,
|
||||
FieldPosition fieldPosition) {
|
||||
|
||||
Objects.requireNonNull(number);
|
||||
@ -773,7 +820,7 @@ public final class CompactNumberFormat extends NumberFormat {
|
||||
return format(number, result, fieldPosition.getFieldDelegate());
|
||||
}
|
||||
|
||||
private StringBuffer format(BigDecimal number, StringBuffer result,
|
||||
private StringBuf format(BigDecimal number, StringBuf result,
|
||||
FieldDelegate delegate) {
|
||||
|
||||
boolean isNegative = number.signum() == -1;
|
||||
@ -843,14 +890,14 @@ public final class CompactNumberFormat extends NumberFormat {
|
||||
* prefix and the suffix fields can be obtained
|
||||
* using {@link NumberFormat.Field#PREFIX} 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
|
||||
* mode being set to {@code RoundingMode.UNNECESSARY}
|
||||
* @throws NullPointerException if any of the given parameter
|
||||
* is {@code null}
|
||||
* @see FieldPosition
|
||||
*/
|
||||
private StringBuffer format(BigInteger number, StringBuffer result,
|
||||
private StringBuf format(BigInteger number, StringBuf result,
|
||||
FieldPosition fieldPosition) {
|
||||
|
||||
Objects.requireNonNull(number);
|
||||
@ -859,7 +906,7 @@ public final class CompactNumberFormat extends NumberFormat {
|
||||
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) {
|
||||
|
||||
boolean isNegative = number.signum() == -1;
|
||||
@ -936,7 +983,7 @@ public final class CompactNumberFormat extends NumberFormat {
|
||||
* {@code NumberFormat.Field.SIGN} and
|
||||
* {@code NumberFormat.Field.PREFIX} fields
|
||||
*/
|
||||
private void appendPrefix(StringBuffer result, String prefix,
|
||||
private void appendPrefix(StringBuf result, String prefix,
|
||||
FieldDelegate delegate) {
|
||||
append(result, expandAffix(prefix), delegate,
|
||||
getFieldPositions(prefix, NumberFormat.Field.PREFIX));
|
||||
@ -952,7 +999,7 @@ public final class CompactNumberFormat extends NumberFormat {
|
||||
* {@code NumberFormat.Field.SIGN} and
|
||||
* {@code NumberFormat.Field.SUFFIX} fields
|
||||
*/
|
||||
private void appendSuffix(StringBuffer result, String suffix,
|
||||
private void appendSuffix(StringBuf result, String suffix,
|
||||
FieldDelegate delegate) {
|
||||
append(result, expandAffix(suffix), delegate,
|
||||
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
|
||||
* string
|
||||
*/
|
||||
private void append(StringBuffer result, String string,
|
||||
private void append(StringBuf result, String string,
|
||||
FieldDelegate delegate, List<FieldPosition> positions) {
|
||||
if (!string.isEmpty()) {
|
||||
int start = result.length();
|
||||
@ -1134,7 +1181,7 @@ public final class CompactNumberFormat extends NumberFormat {
|
||||
public AttributedCharacterIterator formatToCharacterIterator(Object obj) {
|
||||
CharacterIteratorFieldDelegate delegate
|
||||
= new CharacterIteratorFieldDelegate();
|
||||
StringBuffer sb = new StringBuffer();
|
||||
StringBuf sb = StringBufFactory.of();
|
||||
|
||||
if (obj instanceof Double || obj instanceof Float) {
|
||||
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");
|
||||
}
|
||||
|
||||
@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
|
||||
* 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,
|
||||
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.
|
||||
*
|
||||
@ -379,9 +397,15 @@ public abstract class DateFormat extends Format {
|
||||
*/
|
||||
public final String format(Date date)
|
||||
{
|
||||
if ("java.text".equals(getClass().getPackageName())
|
||||
&& "java.text".equals(numberFormat.getClass().getPackageName())) {
|
||||
return format(date, StringBufFactory.of(),
|
||||
DontCareFieldPosition.INSTANCE).toString();
|
||||
} else {
|
||||
return format(date, new StringBuffer(),
|
||||
DontCareFieldPosition.INSTANCE).toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses text from the beginning of the given string to produce a date.
|
||||
|
@ -555,6 +555,28 @@ public class DecimalFormat extends NumberFormat {
|
||||
(number instanceof BigInteger &&
|
||||
((BigInteger)number).bitLength () < 64)) {
|
||||
return format(((Number)number).longValue(), toAppendTo, pos);
|
||||
} else if (number instanceof BigDecimal) {
|
||||
return format((BigDecimal)number, StringBufFactory.of(toAppendTo), pos).asStringBuffer();
|
||||
} else if (number instanceof BigInteger) {
|
||||
return format((BigInteger)number, StringBufFactory.of(toAppendTo), pos).asStringBuffer();
|
||||
} else if (number instanceof Number) {
|
||||
return format(((Number)number).doubleValue(), toAppendTo, pos);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Cannot format given Object as a Number");
|
||||
}
|
||||
}
|
||||
|
||||
@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) {
|
||||
@ -588,6 +610,12 @@ public class DecimalFormat extends NumberFormat {
|
||||
@Override
|
||||
public StringBuffer format(double number, StringBuffer result,
|
||||
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
|
||||
// try to go to fast-path code.
|
||||
boolean tryFastPath = false;
|
||||
@ -619,7 +647,7 @@ public class DecimalFormat extends NumberFormat {
|
||||
* mode being set to RoundingMode.UNNECESSARY
|
||||
* @return The formatted number string
|
||||
*/
|
||||
StringBuffer format(double number, StringBuffer result,
|
||||
StringBuf format(double number, StringBuf result,
|
||||
FieldDelegate delegate) {
|
||||
|
||||
boolean nanOrInfinity = handleNaN(number, result, delegate);
|
||||
@ -666,7 +694,7 @@ public class DecimalFormat extends NumberFormat {
|
||||
* @param delegate notified of locations of sub fields
|
||||
* @return true, if number is a NaN; false otherwise
|
||||
*/
|
||||
boolean handleNaN(double number, StringBuffer result,
|
||||
boolean handleNaN(double number, StringBuf result,
|
||||
FieldDelegate delegate) {
|
||||
if (Double.isNaN(number)
|
||||
|| (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
|
||||
* {@code Double.POSITIVE_INFINITY}; false otherwise
|
||||
*/
|
||||
boolean handleInfinity(double number, StringBuffer result,
|
||||
boolean handleInfinity(double number, StringBuf result,
|
||||
FieldDelegate delegate, boolean isNegative) {
|
||||
if (Double.isInfinite(number)) {
|
||||
if (isNegative) {
|
||||
@ -720,7 +748,7 @@ public class DecimalFormat extends NumberFormat {
|
||||
return false;
|
||||
}
|
||||
|
||||
StringBuffer doubleSubformat(double number, StringBuffer result,
|
||||
StringBuf doubleSubformat(double number, StringBuf result,
|
||||
FieldDelegate delegate, boolean isNegative) {
|
||||
synchronized (digitList) {
|
||||
int maxIntDigits = super.getMaximumIntegerDigits();
|
||||
@ -761,6 +789,14 @@ public class DecimalFormat extends NumberFormat {
|
||||
fieldPosition.setBeginIndex(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());
|
||||
}
|
||||
|
||||
@ -774,7 +810,7 @@ public class DecimalFormat extends NumberFormat {
|
||||
* mode being set to RoundingMode.UNNECESSARY
|
||||
* @see java.text.FieldPosition
|
||||
*/
|
||||
StringBuffer format(long number, StringBuffer result,
|
||||
StringBuf format(long number, StringBuf result,
|
||||
FieldDelegate delegate) {
|
||||
boolean isNegative = (number < 0);
|
||||
if (isNegative) {
|
||||
@ -849,7 +885,7 @@ public class DecimalFormat extends NumberFormat {
|
||||
* mode being set to RoundingMode.UNNECESSARY
|
||||
* @see java.text.FieldPosition
|
||||
*/
|
||||
private StringBuffer format(BigDecimal number, StringBuffer result,
|
||||
private StringBuf format(BigDecimal number, StringBuf result,
|
||||
FieldPosition fieldPosition) {
|
||||
fieldPosition.setBeginIndex(0);
|
||||
fieldPosition.setEndIndex(0);
|
||||
@ -865,7 +901,7 @@ public class DecimalFormat extends NumberFormat {
|
||||
* mode being set to RoundingMode.UNNECESSARY
|
||||
* @return The formatted number string
|
||||
*/
|
||||
StringBuffer format(BigDecimal number, StringBuffer result,
|
||||
StringBuf format(BigDecimal number, StringBuf result,
|
||||
FieldDelegate delegate) {
|
||||
if (multiplier != 1) {
|
||||
number = number.multiply(getBigDecimalMultiplier());
|
||||
@ -908,7 +944,7 @@ public class DecimalFormat extends NumberFormat {
|
||||
* mode being set to RoundingMode.UNNECESSARY
|
||||
* @see java.text.FieldPosition
|
||||
*/
|
||||
private StringBuffer format(BigInteger number, StringBuffer result,
|
||||
private StringBuf format(BigInteger number, StringBuf result,
|
||||
FieldPosition fieldPosition) {
|
||||
fieldPosition.setBeginIndex(0);
|
||||
fieldPosition.setEndIndex(0);
|
||||
@ -926,7 +962,7 @@ public class DecimalFormat extends NumberFormat {
|
||||
* mode being set to RoundingMode.UNNECESSARY
|
||||
* @see java.text.FieldPosition
|
||||
*/
|
||||
StringBuffer format(BigInteger number, StringBuffer result,
|
||||
StringBuf format(BigInteger number, StringBuf result,
|
||||
FieldDelegate delegate, boolean formatLong) {
|
||||
if (multiplier != 1) {
|
||||
number = number.multiply(getBigIntegerMultiplier());
|
||||
@ -986,7 +1022,7 @@ public class DecimalFormat extends NumberFormat {
|
||||
public AttributedCharacterIterator formatToCharacterIterator(Object obj) {
|
||||
CharacterIteratorFieldDelegate delegate =
|
||||
new CharacterIteratorFieldDelegate();
|
||||
StringBuffer sb = new StringBuffer();
|
||||
StringBuf sb = StringBufFactory.of();
|
||||
|
||||
if (obj instanceof Double || obj instanceof Float) {
|
||||
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
|
||||
* 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,
|
||||
int maxIntDigits, int minIntDigits,
|
||||
int maxFraDigits, int minFraDigits) {
|
||||
@ -1821,7 +1857,7 @@ public class DecimalFormat extends NumberFormat {
|
||||
* @param maxFraDigits maximum fraction digits
|
||||
* @param minFraDigits minimum fraction digits
|
||||
*/
|
||||
void subformatNumber(StringBuffer result, FieldDelegate delegate,
|
||||
void subformatNumber(StringBuf result, FieldDelegate delegate,
|
||||
boolean isNegative, boolean isInteger,
|
||||
int maxIntDigits, int minIntDigits,
|
||||
int maxFraDigits, int minFraDigits) {
|
||||
@ -2108,7 +2144,7 @@ public class DecimalFormat extends NumberFormat {
|
||||
* <p>
|
||||
* 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,
|
||||
FieldPosition[] positions,
|
||||
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.
|
||||
*
|
||||
* 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() {
|
||||
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,
|
||||
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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -290,7 +290,7 @@ public class FieldPosition {
|
||||
private boolean encounteredField;
|
||||
|
||||
public void formatted(Format.Field attr, Object value, int start,
|
||||
int end, StringBuffer buffer) {
|
||||
int end, Format.StringBuf buffer) {
|
||||
if (!encounteredField && matchesField(attr)) {
|
||||
setBeginIndex(start);
|
||||
setEndIndex(end);
|
||||
@ -299,7 +299,7 @@ public class FieldPosition {
|
||||
}
|
||||
|
||||
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)) {
|
||||
setBeginIndex(start);
|
||||
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.
|
||||
*
|
||||
* 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>
|
||||
* {@link #format(Object, StringBuffer, FieldPosition) format}<code>(obj,
|
||||
* new StringBuffer(), new FieldPosition(0)).toString();</code>
|
||||
@ -160,8 +161,12 @@ public abstract class Format implements Serializable, Cloneable {
|
||||
* object
|
||||
*/
|
||||
public final String format (Object obj) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats an object and appends the resulting text to a given string
|
||||
@ -185,6 +190,12 @@ public abstract class Format implements Serializable, Cloneable {
|
||||
StringBuffer toAppendTo,
|
||||
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}.
|
||||
* You can use the returned {@code AttributedCharacterIterator}
|
||||
@ -394,7 +405,7 @@ public abstract class Format implements Serializable, Cloneable {
|
||||
* NOT modify it.
|
||||
*/
|
||||
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.
|
||||
@ -408,6 +419,38 @@ public abstract class Format implements Serializable, Cloneable {
|
||||
* NOT modify it.
|
||||
*/
|
||||
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) {
|
||||
Objects.requireNonNull(input);
|
||||
|
||||
return format(input, new StringBuffer(),
|
||||
return format(input, StringBufFactory.of(),
|
||||
DontCareFieldPosition.INSTANCE).toString();
|
||||
}
|
||||
|
||||
@ -381,6 +381,18 @@ public final class ListFormat extends Format {
|
||||
Objects.requireNonNull(obj);
|
||||
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) {
|
||||
return generateMessageFormat(objs).format(objs, toAppendTo, DontCareFieldPosition.INSTANCE);
|
||||
} else if (obj instanceof List<?> objs) {
|
||||
|
@ -1027,12 +1027,13 @@ public class MessageFormat extends Format {
|
||||
public final StringBuffer format(Object[] arguments, StringBuffer result,
|
||||
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
|
||||
* 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>
|
||||
* <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>
|
||||
@ -1076,6 +1077,12 @@ public class MessageFormat extends Format {
|
||||
public final StringBuffer format(Object arguments, StringBuffer result,
|
||||
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);
|
||||
}
|
||||
|
||||
@ -1116,7 +1123,7 @@ public class MessageFormat extends Format {
|
||||
*/
|
||||
public AttributedCharacterIterator formatToCharacterIterator(Object arguments) {
|
||||
Objects.requireNonNull(arguments, "arguments must not be null");
|
||||
StringBuffer result = new StringBuffer();
|
||||
StringBuf result = StringBufFactory.of();
|
||||
ArrayList<AttributedCharacterIterator> iterators = new ArrayList<>();
|
||||
|
||||
subformat((Object[]) arguments, result, null, iterators);
|
||||
@ -1472,7 +1479,7 @@ public class MessageFormat extends Format {
|
||||
* {@code arguments} array is not of the type
|
||||
* 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) {
|
||||
// note: this implementation assumes a fast substring & index.
|
||||
// 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
|
||||
* {@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) {
|
||||
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}
|
||||
*
|
||||
@ -347,9 +364,14 @@ public abstract class NumberFormat extends Format {
|
||||
if (result != null)
|
||||
return result;
|
||||
|
||||
if ("java.text".equals(getClass().getPackageName())) {
|
||||
return format(number, StringBufFactory.of(),
|
||||
DontCareFieldPosition.INSTANCE).toString();
|
||||
} else {
|
||||
return format(number, new StringBuffer(),
|
||||
DontCareFieldPosition.INSTANCE).toString();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* fastFormat() is supposed to be implemented in concrete subclasses only.
|
||||
@ -367,9 +389,14 @@ public abstract class NumberFormat extends Format {
|
||||
* @see java.text.Format#format
|
||||
*/
|
||||
public final String format(long number) {
|
||||
if ("java.text".equals(getClass().getPackageName())) {
|
||||
return format(number, StringBufFactory.of(),
|
||||
DontCareFieldPosition.INSTANCE).toString();
|
||||
} else {
|
||||
return format(number, new StringBuffer(),
|
||||
DontCareFieldPosition.INSTANCE).toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Specialization of format.
|
||||
@ -394,6 +421,12 @@ public abstract class NumberFormat extends Format {
|
||||
StringBuffer toAppendTo,
|
||||
FieldPosition pos);
|
||||
|
||||
StringBuf format(double number,
|
||||
StringBuf toAppendTo,
|
||||
FieldPosition pos) {
|
||||
throw new UnsupportedOperationException("Subclasses should override this method");
|
||||
}
|
||||
|
||||
/**
|
||||
* Specialization of format.
|
||||
*
|
||||
@ -417,6 +450,12 @@ public abstract class NumberFormat extends Format {
|
||||
StringBuffer toAppendTo,
|
||||
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}.
|
||||
* <p>
|
||||
|
@ -968,11 +968,18 @@ public class SimpleDateFormat extends DateFormat {
|
||||
FieldPosition pos)
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
||||
// Called from Format after creating a FieldDelegate
|
||||
private StringBuffer format(Date date, StringBuffer toAppendTo,
|
||||
private StringBuf format(Date date, StringBuf toAppendTo,
|
||||
FieldDelegate delegate) {
|
||||
// Convert input date to time field list
|
||||
calendar.setTime(date);
|
||||
@ -1024,7 +1031,7 @@ public class SimpleDateFormat extends DateFormat {
|
||||
*/
|
||||
@Override
|
||||
public AttributedCharacterIterator formatToCharacterIterator(Object obj) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
StringBuf sb = StringBufFactory.of();
|
||||
CharacterIteratorFieldDelegate delegate = new
|
||||
CharacterIteratorFieldDelegate();
|
||||
|
||||
@ -1130,7 +1137,7 @@ public class SimpleDateFormat extends DateFormat {
|
||||
* Private member function that does the real date/time formatting.
|
||||
*/
|
||||
private void subFormat(int patternCharIndex, int count,
|
||||
FieldDelegate delegate, StringBuffer buffer,
|
||||
FieldDelegate delegate, StringBuf buffer,
|
||||
boolean useDateFormatSymbols)
|
||||
{
|
||||
int maxIntCount = Integer.MAX_VALUE;
|
||||
@ -1320,7 +1327,11 @@ public class SimpleDateFormat extends DateFormat {
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
case PATTERN_ISO_ZONE: // 'X'
|
||||
@ -1340,7 +1351,11 @@ public class SimpleDateFormat extends DateFormat {
|
||||
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) {
|
||||
break;
|
||||
}
|
||||
@ -1348,7 +1363,11 @@ public class SimpleDateFormat extends DateFormat {
|
||||
if (count == 3) {
|
||||
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;
|
||||
|
||||
default:
|
||||
@ -1382,7 +1401,7 @@ public class SimpleDateFormat extends DateFormat {
|
||||
/**
|
||||
* 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
|
||||
// cover most cases of formatting date/time related items.
|
||||
@ -1425,7 +1444,17 @@ public class SimpleDateFormat extends DateFormat {
|
||||
|
||||
numberFormat.setMinimumIntegerDigits(minDigits);
|
||||
numberFormat.setMaximumIntegerDigits(maxDigits);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
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