1 |
/* |
2 |
* Written by Martin Buchholz with assistance from members of JCP |
3 |
* JSR-166 Expert Group and released to the public domain, as |
4 |
* explained at http://creativecommons.org/publicdomain/zero/1.0/ |
5 |
*/ |
6 |
|
7 |
package java.util.concurrent; |
8 |
|
9 |
import java.util.Collection; |
10 |
|
11 |
/** Shared implementation code for java.util.concurrent. */ |
12 |
class Helpers { |
13 |
private Helpers() {} // non-instantiable |
14 |
|
15 |
/** |
16 |
* An implementation of Collection.toString() suitable for classes |
17 |
* with locks. Instead of holding a lock for the entire duration of |
18 |
* toString(), or acquiring a lock for each call to Iterator.next(), |
19 |
* we hold the lock only during the call to toArray() (less |
20 |
* disruptive to other threads accessing the collection) and follows |
21 |
* the maxim "Never call foreign code while holding a lock". |
22 |
*/ |
23 |
static String collectionToString(Collection<?> c) { |
24 |
final Object[] a = c.toArray(); |
25 |
final int size = a.length; |
26 |
if (size == 0) |
27 |
return "[]"; |
28 |
int charLength = 0; |
29 |
|
30 |
// Replace every array element with its string representation |
31 |
for (int i = 0; i < size; i++) { |
32 |
Object e = a[i]; |
33 |
// Extreme compatibility with AbstractCollection.toString() |
34 |
String s = (e == c) ? "(this Collection)" : objectToString(e); |
35 |
a[i] = s; |
36 |
charLength += s.length(); |
37 |
} |
38 |
|
39 |
return toString(a, size, charLength); |
40 |
} |
41 |
|
42 |
/** |
43 |
* Like Arrays.toString(), but caller guarantees that size > 0, |
44 |
* each element with index 0 <= i < size is a non-null String, |
45 |
* and charLength is the sum of the lengths of the input Strings. |
46 |
*/ |
47 |
static String toString(Object[] a, int size, int charLength) { |
48 |
// assert a != null; |
49 |
// assert size > 0; |
50 |
|
51 |
// Copy each string into a perfectly sized char[] |
52 |
// Length of [ , , , ] == 2 * size |
53 |
final char[] chars = new char[charLength + 2 * size]; |
54 |
chars[0] = '['; |
55 |
int j = 1; |
56 |
for (int i = 0; i < size; i++) { |
57 |
if (i > 0) { |
58 |
chars[j++] = ','; |
59 |
chars[j++] = ' '; |
60 |
} |
61 |
String s = (String) a[i]; |
62 |
int len = s.length(); |
63 |
s.getChars(0, len, chars, j); |
64 |
j += len; |
65 |
} |
66 |
chars[j] = ']'; |
67 |
// assert j == chars.length - 1; |
68 |
return new String(chars); |
69 |
} |
70 |
|
71 |
/** Optimized form of: key + "=" + val */ |
72 |
static String mapEntryToString(Object key, Object val) { |
73 |
final String k, v; |
74 |
final int klen, vlen; |
75 |
final char[] chars = |
76 |
new char[(klen = (k = objectToString(key)).length()) + |
77 |
(vlen = (v = objectToString(val)).length()) + 1]; |
78 |
k.getChars(0, klen, chars, 0); |
79 |
chars[klen] = '='; |
80 |
v.getChars(0, vlen, chars, klen + 1); |
81 |
return new String(chars); |
82 |
} |
83 |
|
84 |
private static String objectToString(Object x) { |
85 |
// Extreme compatibility with StringBuilder.append(null) |
86 |
String s; |
87 |
return (x == null || (s = x.toString()) == null) ? "null" : s; |
88 |
} |
89 |
} |