1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 package groovy.lang;
47
48 import java.util.AbstractList;
49 import java.util.List;
50
51 import org.codehaus.groovy.runtime.InvokerHelper;
52
53 /***
54 * Spreads a list as individual objects to support the spread operator (*) for lists.
55 * For examples, <pre>
56 * def fn(a, b, c, d) { return a + b + c + d }
57 * println fn(1, 2, 3, 4)
58 *
59 * def x = [10, 100]
60 * def y = [1, *x, 1000, *[10000, 100000]]
61 * assert y == [1, 10, 100, 1000, 10000, 100000]
62 * </pre><br>
63 *
64 * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
65 * @author Pilho Kim
66 * @version $Revision: 1.6 $
67 */
68 public class SpreadList extends AbstractList {
69
70 private Object[] contents;
71 private int hashCode;
72
73 /***
74 * Generator.
75 *
76 * @param contents an array of objects to be converted to a SpreadList
77 */
78 public SpreadList(Object[] contents) {
79 this.contents = contents;
80 }
81
82 /***
83 * Returns the object in <code>this</code> of the indicated position.
84 *
85 * @param index the indicated position in <code>this</code>
86 */
87 public Object get(int index) {
88 return contents[index];
89 }
90
91 /***
92 * Returns the size of <code>this</code>.
93 *
94 * @param index the indicated position in <code>this</code>
95 */
96 public int size() {
97 return contents.length;
98 }
99
100 /***
101 * Compares <code>this</code> with another object.
102 *
103 * @param that another object to be compared with <code>this</code>
104 * @return Returns <code>true</code> if this equals to <code>that</code>, <code>false</code> otherwise
105 */
106 public boolean equals(Object that) {
107 if (that instanceof SpreadList) {
108 return equals((SpreadList) that);
109 }
110 return false;
111 }
112
113 /***
114 * Compares <code>this</code> with another spreadlist.
115 *
116 * @param that another spreadlist to be compared with <code>this</code>
117 * @return Returns <code>true</code> if this equals to <code>that</code>, <code>false</code> otherwise
118 */
119 public boolean equals(SpreadList that) {
120 if (contents.length == that.contents.length) {
121 for (int i = 0; i < contents.length; i++) {
122 if (! InvokerHelper.compareEqual(this.contents[i], that.contents[i])) {
123 return false;
124 }
125 }
126 return true;
127 }
128 return false;
129 }
130
131
132 /***
133 * Returns the hash code of <code>this</code>.
134 *
135 * @return Returns the hash code of <code>this</code>
136 */
137 public int hashCode() {
138 if (hashCode == 0) {
139 for (int i = 0; i < contents.length; i++ ) {
140 Object value = contents[i];
141 int hash = (value != null) ? value.hashCode() : 0xbabe;
142 hashCode ^= hash;
143 }
144 if (hashCode == 0) {
145 hashCode = 0xbabe;
146 }
147 }
148 return hashCode;
149 }
150
151 /***
152 * Returns a sublist of <code>this</code> from <code>fromIndex</code> to <code>toIndex</code>.
153 *
154 * @param fromIndex the first index in <code>this</code> to be taken
155 * @param toIndex the last index in <code>this</code> to be taken
156 * @return Returns the sublist of <code>thin</code> in the given scope
157 */
158 public List subList(int fromIndex, int toIndex) {
159 int size = toIndex - fromIndex;
160 Object[] newContent = new Object[size];
161 System.arraycopy(contents, fromIndex, newContent, 0, size);
162 return new SpreadList(newContent);
163 }
164
165 /***
166 * Returns the string expression of <code>this</code>.
167 *
168 * @return Returns the string expression of <code>this</code>
169 */
170 public String toString() {
171 return "*" + super.toString();
172 }
173 }