8020977: StringJoiner merges with itself not as expected
Reviewed-by: psandoz, chegar, mduigou, smarks
--- a/jdk/src/share/classes/java/util/StringJoiner.java Tue Jul 30 14:43:19 2013 -0700
+++ b/jdk/src/share/classes/java/util/StringJoiner.java Tue Jul 30 15:47:35 2013 -0700
@@ -206,11 +206,12 @@
public StringJoiner merge(StringJoiner other) {
Objects.requireNonNull(other);
if (other.value != null) {
+ final int length = other.value.length();
+ // lock the length so that we can seize the data to be appended
+ // before initiate copying to avoid interference, especially when
+ // merge 'this'
StringBuilder builder = prepareBuilder();
- StringBuilder otherBuilder = other.value;
- if (other.prefix.length() < otherBuilder.length()) {
- builder.append(otherBuilder, other.prefix.length(), otherBuilder.length());
- }
+ builder.append(other.value, other.prefix.length(), length);
}
return this;
}
--- a/jdk/test/java/util/StringJoiner/MergeTest.java Tue Jul 30 14:43:19 2013 -0700
+++ b/jdk/test/java/util/StringJoiner/MergeTest.java Tue Jul 30 15:47:35 2013 -0700
@@ -23,7 +23,7 @@
/**
* @test
- * @bug 8017231
+ * @bug 8017231 8020977
* @summary test StringJoiner::merge
* @run testng MergeTest
*/
@@ -121,4 +121,13 @@
sj.merge(other);
assertEquals(sj.toString(), "{a,b,c,d:e:f}");
}
-}
\ No newline at end of file
+
+ public void testMergeSelf() {
+ final StringJoiner sj = new StringJoiner(",", "[", "]").add("a").add("b");
+ assertEquals(sj.merge(sj).toString(), "[a,b,a,b]");
+ assertEquals(sj.merge(sj).toString(), "[a,b,a,b,a,b,a,b]");
+
+ final StringJoiner sj2 = new StringJoiner(",").add("c").add("d");
+ assertEquals(sj2.merge(sj2).toString(), "c,d,c,d");
+ }
+}