122 * input arrays to n/2 object references for randomly ordered input |
122 * input arrays to n/2 object references for randomly ordered input |
123 * arrays. |
123 * arrays. |
124 * |
124 * |
125 * <p>The implementation takes equal advantage of ascending and |
125 * <p>The implementation takes equal advantage of ascending and |
126 * descending order in its input array, and can take advantage of |
126 * descending order in its input array, and can take advantage of |
127 * ascending and descending order in different parts of the the same |
127 * ascending and descending order in different parts of the same |
128 * input array. It is well-suited to merging two or more sorted arrays: |
128 * input array. It is well-suited to merging two or more sorted arrays: |
129 * simply concatenate the arrays and sort the resulting array. |
129 * simply concatenate the arrays and sort the resulting array. |
130 * |
130 * |
131 * <p>The implementation was adapted from Tim Peters's list sort for Python |
131 * <p>The implementation was adapted from Tim Peters's list sort for Python |
132 * (<a href="http://svn.python.org/projects/python/trunk/Objects/listsort.txt"> |
132 * (<a href="http://svn.python.org/projects/python/trunk/Objects/listsort.txt"> |
182 * input arrays to n/2 object references for randomly ordered input |
182 * input arrays to n/2 object references for randomly ordered input |
183 * arrays. |
183 * arrays. |
184 * |
184 * |
185 * <p>The implementation takes equal advantage of ascending and |
185 * <p>The implementation takes equal advantage of ascending and |
186 * descending order in its input array, and can take advantage of |
186 * descending order in its input array, and can take advantage of |
187 * ascending and descending order in different parts of the the same |
187 * ascending and descending order in different parts of the same |
188 * input array. It is well-suited to merging two or more sorted arrays: |
188 * input array. It is well-suited to merging two or more sorted arrays: |
189 * simply concatenate the arrays and sort the resulting array. |
189 * simply concatenate the arrays and sort the resulting array. |
190 * |
190 * |
191 * <p>The implementation was adapted from Tim Peters's list sort for Python |
191 * <p>The implementation was adapted from Tim Peters's list sort for Python |
192 * (<a href="http://svn.python.org/projects/python/trunk/Objects/listsort.txt"> |
192 * (<a href="http://svn.python.org/projects/python/trunk/Objects/listsort.txt"> |
1450 * The next two methods are overridden to protect against |
1450 * The next two methods are overridden to protect against |
1451 * an unscrupulous List whose contains(Object o) method senses |
1451 * an unscrupulous List whose contains(Object o) method senses |
1452 * when o is a Map.Entry, and calls o.setValue. |
1452 * when o is a Map.Entry, and calls o.setValue. |
1453 */ |
1453 */ |
1454 public boolean containsAll(Collection<?> coll) { |
1454 public boolean containsAll(Collection<?> coll) { |
1455 Iterator<?> e = coll.iterator(); |
1455 Iterator<?> it = coll.iterator(); |
1456 while (e.hasNext()) |
1456 while (it.hasNext()) |
1457 if (!contains(e.next())) // Invokes safe contains() above |
1457 if (!contains(it.next())) // Invokes safe contains() above |
1458 return false; |
1458 return false; |
1459 return true; |
1459 return true; |
1460 } |
1460 } |
1461 public boolean equals(Object o) { |
1461 public boolean equals(Object o) { |
1462 if (o == this) |
1462 if (o == this) |
1480 private static class UnmodifiableEntry<K,V> implements Map.Entry<K,V> { |
1480 private static class UnmodifiableEntry<K,V> implements Map.Entry<K,V> { |
1481 private Map.Entry<? extends K, ? extends V> e; |
1481 private Map.Entry<? extends K, ? extends V> e; |
1482 |
1482 |
1483 UnmodifiableEntry(Map.Entry<? extends K, ? extends V> e) {this.e = e;} |
1483 UnmodifiableEntry(Map.Entry<? extends K, ? extends V> e) {this.e = e;} |
1484 |
1484 |
1485 public K getKey() {return e.getKey();} |
1485 public K getKey() {return e.getKey();} |
1486 public V getValue() {return e.getValue();} |
1486 public V getValue() {return e.getValue();} |
1487 public V setValue(V value) { |
1487 public V setValue(V value) { |
1488 throw new UnsupportedOperationException(); |
1488 throw new UnsupportedOperationException(); |
1489 } |
1489 } |
1490 public int hashCode() {return e.hashCode();} |
1490 public int hashCode() {return e.hashCode();} |
1491 public boolean equals(Object o) { |
1491 public boolean equals(Object o) { |
1492 if (!(o instanceof Map.Entry)) |
1492 if (!(o instanceof Map.Entry)) |
1493 return false; |
1493 return false; |
1494 Map.Entry t = (Map.Entry)o; |
1494 Map.Entry t = (Map.Entry)o; |
1495 return eq(e.getKey(), t.getKey()) && |
1495 return eq(e.getKey(), t.getKey()) && |
1496 eq(e.getValue(), t.getValue()); |
1496 eq(e.getValue(), t.getValue()); |
1497 } |
1497 } |
1498 public String toString() {return e.toString();} |
1498 public String toString() {return e.toString();} |
1499 } |
1499 } |
1500 } |
1500 } |
1501 } |
1501 } |
1502 |
1502 |
1503 /** |
1503 /** |
1609 this.c = c; |
1609 this.c = c; |
1610 this.mutex = mutex; |
1610 this.mutex = mutex; |
1611 } |
1611 } |
1612 |
1612 |
1613 public int size() { |
1613 public int size() { |
1614 synchronized(mutex) {return c.size();} |
1614 synchronized (mutex) {return c.size();} |
1615 } |
1615 } |
1616 public boolean isEmpty() { |
1616 public boolean isEmpty() { |
1617 synchronized(mutex) {return c.isEmpty();} |
1617 synchronized (mutex) {return c.isEmpty();} |
1618 } |
1618 } |
1619 public boolean contains(Object o) { |
1619 public boolean contains(Object o) { |
1620 synchronized(mutex) {return c.contains(o);} |
1620 synchronized (mutex) {return c.contains(o);} |
1621 } |
1621 } |
1622 public Object[] toArray() { |
1622 public Object[] toArray() { |
1623 synchronized(mutex) {return c.toArray();} |
1623 synchronized (mutex) {return c.toArray();} |
1624 } |
1624 } |
1625 public <T> T[] toArray(T[] a) { |
1625 public <T> T[] toArray(T[] a) { |
1626 synchronized(mutex) {return c.toArray(a);} |
1626 synchronized (mutex) {return c.toArray(a);} |
1627 } |
1627 } |
1628 |
1628 |
1629 public Iterator<E> iterator() { |
1629 public Iterator<E> iterator() { |
1630 return c.iterator(); // Must be manually synched by user! |
1630 return c.iterator(); // Must be manually synched by user! |
1631 } |
1631 } |
1632 |
1632 |
1633 public boolean add(E e) { |
1633 public boolean add(E e) { |
1634 synchronized(mutex) {return c.add(e);} |
1634 synchronized (mutex) {return c.add(e);} |
1635 } |
1635 } |
1636 public boolean remove(Object o) { |
1636 public boolean remove(Object o) { |
1637 synchronized(mutex) {return c.remove(o);} |
1637 synchronized (mutex) {return c.remove(o);} |
1638 } |
1638 } |
1639 |
1639 |
1640 public boolean containsAll(Collection<?> coll) { |
1640 public boolean containsAll(Collection<?> coll) { |
1641 synchronized(mutex) {return c.containsAll(coll);} |
1641 synchronized (mutex) {return c.containsAll(coll);} |
1642 } |
1642 } |
1643 public boolean addAll(Collection<? extends E> coll) { |
1643 public boolean addAll(Collection<? extends E> coll) { |
1644 synchronized(mutex) {return c.addAll(coll);} |
1644 synchronized (mutex) {return c.addAll(coll);} |
1645 } |
1645 } |
1646 public boolean removeAll(Collection<?> coll) { |
1646 public boolean removeAll(Collection<?> coll) { |
1647 synchronized(mutex) {return c.removeAll(coll);} |
1647 synchronized (mutex) {return c.removeAll(coll);} |
1648 } |
1648 } |
1649 public boolean retainAll(Collection<?> coll) { |
1649 public boolean retainAll(Collection<?> coll) { |
1650 synchronized(mutex) {return c.retainAll(coll);} |
1650 synchronized (mutex) {return c.retainAll(coll);} |
1651 } |
1651 } |
1652 public void clear() { |
1652 public void clear() { |
1653 synchronized(mutex) {c.clear();} |
1653 synchronized (mutex) {c.clear();} |
1654 } |
1654 } |
1655 public String toString() { |
1655 public String toString() { |
1656 synchronized(mutex) {return c.toString();} |
1656 synchronized (mutex) {return c.toString();} |
1657 } |
1657 } |
1658 private void writeObject(ObjectOutputStream s) throws IOException { |
1658 private void writeObject(ObjectOutputStream s) throws IOException { |
1659 synchronized(mutex) {s.defaultWriteObject();} |
1659 synchronized (mutex) {s.defaultWriteObject();} |
1660 } |
1660 } |
1661 } |
1661 } |
1662 |
1662 |
1663 /** |
1663 /** |
1664 * Returns a synchronized (thread-safe) set backed by the specified |
1664 * Returns a synchronized (thread-safe) set backed by the specified |
1726 * sorted set when iterating over it or any of its <tt>subSet</tt>, |
1726 * sorted set when iterating over it or any of its <tt>subSet</tt>, |
1727 * <tt>headSet</tt>, or <tt>tailSet</tt> views. |
1727 * <tt>headSet</tt>, or <tt>tailSet</tt> views. |
1728 * <pre> |
1728 * <pre> |
1729 * SortedSet s = Collections.synchronizedSortedSet(new TreeSet()); |
1729 * SortedSet s = Collections.synchronizedSortedSet(new TreeSet()); |
1730 * ... |
1730 * ... |
1731 * synchronized(s) { |
1731 * synchronized (s) { |
1732 * Iterator i = s.iterator(); // Must be in the synchronized block |
1732 * Iterator i = s.iterator(); // Must be in the synchronized block |
1733 * while (i.hasNext()) |
1733 * while (i.hasNext()) |
1734 * foo(i.next()); |
1734 * foo(i.next()); |
1735 * } |
1735 * } |
1736 * </pre> |
1736 * </pre> |
1737 * or: |
1737 * or: |
1738 * <pre> |
1738 * <pre> |
1739 * SortedSet s = Collections.synchronizedSortedSet(new TreeSet()); |
1739 * SortedSet s = Collections.synchronizedSortedSet(new TreeSet()); |
1740 * SortedSet s2 = s.headSet(foo); |
1740 * SortedSet s2 = s.headSet(foo); |
1741 * ... |
1741 * ... |
1742 * synchronized(s) { // Note: s, not s2!!! |
1742 * synchronized (s) { // Note: s, not s2!!! |
1743 * Iterator i = s2.iterator(); // Must be in the synchronized block |
1743 * Iterator i = s2.iterator(); // Must be in the synchronized block |
1744 * while (i.hasNext()) |
1744 * while (i.hasNext()) |
1745 * foo(i.next()); |
1745 * foo(i.next()); |
1746 * } |
1746 * } |
1747 * </pre> |
1747 * </pre> |
1776 super(s, mutex); |
1776 super(s, mutex); |
1777 ss = s; |
1777 ss = s; |
1778 } |
1778 } |
1779 |
1779 |
1780 public Comparator<? super E> comparator() { |
1780 public Comparator<? super E> comparator() { |
1781 synchronized(mutex) {return ss.comparator();} |
1781 synchronized (mutex) {return ss.comparator();} |
1782 } |
1782 } |
1783 |
1783 |
1784 public SortedSet<E> subSet(E fromElement, E toElement) { |
1784 public SortedSet<E> subSet(E fromElement, E toElement) { |
1785 synchronized(mutex) { |
1785 synchronized (mutex) { |
1786 return new SynchronizedSortedSet<E>( |
1786 return new SynchronizedSortedSet<E>( |
1787 ss.subSet(fromElement, toElement), mutex); |
1787 ss.subSet(fromElement, toElement), mutex); |
1788 } |
1788 } |
1789 } |
1789 } |
1790 public SortedSet<E> headSet(E toElement) { |
1790 public SortedSet<E> headSet(E toElement) { |
1791 synchronized(mutex) { |
1791 synchronized (mutex) { |
1792 return new SynchronizedSortedSet<E>(ss.headSet(toElement), mutex); |
1792 return new SynchronizedSortedSet<E>(ss.headSet(toElement), mutex); |
1793 } |
1793 } |
1794 } |
1794 } |
1795 public SortedSet<E> tailSet(E fromElement) { |
1795 public SortedSet<E> tailSet(E fromElement) { |
1796 synchronized(mutex) { |
1796 synchronized (mutex) { |
1797 return new SynchronizedSortedSet<E>(ss.tailSet(fromElement),mutex); |
1797 return new SynchronizedSortedSet<E>(ss.tailSet(fromElement),mutex); |
1798 } |
1798 } |
1799 } |
1799 } |
1800 |
1800 |
1801 public E first() { |
1801 public E first() { |
1802 synchronized(mutex) {return ss.first();} |
1802 synchronized (mutex) {return ss.first();} |
1803 } |
1803 } |
1804 public E last() { |
1804 public E last() { |
1805 synchronized(mutex) {return ss.last();} |
1805 synchronized (mutex) {return ss.last();} |
1806 } |
1806 } |
1807 } |
1807 } |
1808 |
1808 |
1809 /** |
1809 /** |
1810 * Returns a synchronized (thread-safe) list backed by the specified |
1810 * Returns a synchronized (thread-safe) list backed by the specified |
1861 super(list, mutex); |
1861 super(list, mutex); |
1862 this.list = list; |
1862 this.list = list; |
1863 } |
1863 } |
1864 |
1864 |
1865 public boolean equals(Object o) { |
1865 public boolean equals(Object o) { |
1866 synchronized(mutex) {return list.equals(o);} |
1866 synchronized (mutex) {return list.equals(o);} |
1867 } |
1867 } |
1868 public int hashCode() { |
1868 public int hashCode() { |
1869 synchronized(mutex) {return list.hashCode();} |
1869 synchronized (mutex) {return list.hashCode();} |
1870 } |
1870 } |
1871 |
1871 |
1872 public E get(int index) { |
1872 public E get(int index) { |
1873 synchronized(mutex) {return list.get(index);} |
1873 synchronized (mutex) {return list.get(index);} |
1874 } |
1874 } |
1875 public E set(int index, E element) { |
1875 public E set(int index, E element) { |
1876 synchronized(mutex) {return list.set(index, element);} |
1876 synchronized (mutex) {return list.set(index, element);} |
1877 } |
1877 } |
1878 public void add(int index, E element) { |
1878 public void add(int index, E element) { |
1879 synchronized(mutex) {list.add(index, element);} |
1879 synchronized (mutex) {list.add(index, element);} |
1880 } |
1880 } |
1881 public E remove(int index) { |
1881 public E remove(int index) { |
1882 synchronized(mutex) {return list.remove(index);} |
1882 synchronized (mutex) {return list.remove(index);} |
1883 } |
1883 } |
1884 |
1884 |
1885 public int indexOf(Object o) { |
1885 public int indexOf(Object o) { |
1886 synchronized(mutex) {return list.indexOf(o);} |
1886 synchronized (mutex) {return list.indexOf(o);} |
1887 } |
1887 } |
1888 public int lastIndexOf(Object o) { |
1888 public int lastIndexOf(Object o) { |
1889 synchronized(mutex) {return list.lastIndexOf(o);} |
1889 synchronized (mutex) {return list.lastIndexOf(o);} |
1890 } |
1890 } |
1891 |
1891 |
1892 public boolean addAll(int index, Collection<? extends E> c) { |
1892 public boolean addAll(int index, Collection<? extends E> c) { |
1893 synchronized(mutex) {return list.addAll(index, c);} |
1893 synchronized (mutex) {return list.addAll(index, c);} |
1894 } |
1894 } |
1895 |
1895 |
1896 public ListIterator<E> listIterator() { |
1896 public ListIterator<E> listIterator() { |
1897 return list.listIterator(); // Must be manually synched by user |
1897 return list.listIterator(); // Must be manually synched by user |
1898 } |
1898 } |
2014 this.m = m; |
2014 this.m = m; |
2015 this.mutex = mutex; |
2015 this.mutex = mutex; |
2016 } |
2016 } |
2017 |
2017 |
2018 public int size() { |
2018 public int size() { |
2019 synchronized(mutex) {return m.size();} |
2019 synchronized (mutex) {return m.size();} |
2020 } |
2020 } |
2021 public boolean isEmpty() { |
2021 public boolean isEmpty() { |
2022 synchronized(mutex) {return m.isEmpty();} |
2022 synchronized (mutex) {return m.isEmpty();} |
2023 } |
2023 } |
2024 public boolean containsKey(Object key) { |
2024 public boolean containsKey(Object key) { |
2025 synchronized(mutex) {return m.containsKey(key);} |
2025 synchronized (mutex) {return m.containsKey(key);} |
2026 } |
2026 } |
2027 public boolean containsValue(Object value) { |
2027 public boolean containsValue(Object value) { |
2028 synchronized(mutex) {return m.containsValue(value);} |
2028 synchronized (mutex) {return m.containsValue(value);} |
2029 } |
2029 } |
2030 public V get(Object key) { |
2030 public V get(Object key) { |
2031 synchronized(mutex) {return m.get(key);} |
2031 synchronized (mutex) {return m.get(key);} |
2032 } |
2032 } |
2033 |
2033 |
2034 public V put(K key, V value) { |
2034 public V put(K key, V value) { |
2035 synchronized(mutex) {return m.put(key, value);} |
2035 synchronized (mutex) {return m.put(key, value);} |
2036 } |
2036 } |
2037 public V remove(Object key) { |
2037 public V remove(Object key) { |
2038 synchronized(mutex) {return m.remove(key);} |
2038 synchronized (mutex) {return m.remove(key);} |
2039 } |
2039 } |
2040 public void putAll(Map<? extends K, ? extends V> map) { |
2040 public void putAll(Map<? extends K, ? extends V> map) { |
2041 synchronized(mutex) {m.putAll(map);} |
2041 synchronized (mutex) {m.putAll(map);} |
2042 } |
2042 } |
2043 public void clear() { |
2043 public void clear() { |
2044 synchronized(mutex) {m.clear();} |
2044 synchronized (mutex) {m.clear();} |
2045 } |
2045 } |
2046 |
2046 |
2047 private transient Set<K> keySet = null; |
2047 private transient Set<K> keySet = null; |
2048 private transient Set<Map.Entry<K,V>> entrySet = null; |
2048 private transient Set<Map.Entry<K,V>> entrySet = null; |
2049 private transient Collection<V> values = null; |
2049 private transient Collection<V> values = null; |
2050 |
2050 |
2051 public Set<K> keySet() { |
2051 public Set<K> keySet() { |
2052 synchronized(mutex) { |
2052 synchronized (mutex) { |
2053 if (keySet==null) |
2053 if (keySet==null) |
2054 keySet = new SynchronizedSet<K>(m.keySet(), mutex); |
2054 keySet = new SynchronizedSet<K>(m.keySet(), mutex); |
2055 return keySet; |
2055 return keySet; |
2056 } |
2056 } |
2057 } |
2057 } |
2058 |
2058 |
2059 public Set<Map.Entry<K,V>> entrySet() { |
2059 public Set<Map.Entry<K,V>> entrySet() { |
2060 synchronized(mutex) { |
2060 synchronized (mutex) { |
2061 if (entrySet==null) |
2061 if (entrySet==null) |
2062 entrySet = new SynchronizedSet<Map.Entry<K,V>>(m.entrySet(), mutex); |
2062 entrySet = new SynchronizedSet<Map.Entry<K,V>>(m.entrySet(), mutex); |
2063 return entrySet; |
2063 return entrySet; |
2064 } |
2064 } |
2065 } |
2065 } |
2066 |
2066 |
2067 public Collection<V> values() { |
2067 public Collection<V> values() { |
2068 synchronized(mutex) { |
2068 synchronized (mutex) { |
2069 if (values==null) |
2069 if (values==null) |
2070 values = new SynchronizedCollection<V>(m.values(), mutex); |
2070 values = new SynchronizedCollection<V>(m.values(), mutex); |
2071 return values; |
2071 return values; |
2072 } |
2072 } |
2073 } |
2073 } |
2074 |
2074 |
2075 public boolean equals(Object o) { |
2075 public boolean equals(Object o) { |
2076 synchronized(mutex) {return m.equals(o);} |
2076 synchronized (mutex) {return m.equals(o);} |
2077 } |
2077 } |
2078 public int hashCode() { |
2078 public int hashCode() { |
2079 synchronized(mutex) {return m.hashCode();} |
2079 synchronized (mutex) {return m.hashCode();} |
2080 } |
2080 } |
2081 public String toString() { |
2081 public String toString() { |
2082 synchronized(mutex) {return m.toString();} |
2082 synchronized (mutex) {return m.toString();} |
2083 } |
2083 } |
2084 private void writeObject(ObjectOutputStream s) throws IOException { |
2084 private void writeObject(ObjectOutputStream s) throws IOException { |
2085 synchronized(mutex) {s.defaultWriteObject();} |
2085 synchronized (mutex) {s.defaultWriteObject();} |
2086 } |
2086 } |
2087 } |
2087 } |
2088 |
2088 |
2089 /** |
2089 /** |
2090 * Returns a synchronized (thread-safe) sorted map backed by the specified |
2090 * Returns a synchronized (thread-safe) sorted map backed by the specified |
2152 super(m, mutex); |
2152 super(m, mutex); |
2153 sm = m; |
2153 sm = m; |
2154 } |
2154 } |
2155 |
2155 |
2156 public Comparator<? super K> comparator() { |
2156 public Comparator<? super K> comparator() { |
2157 synchronized(mutex) {return sm.comparator();} |
2157 synchronized (mutex) {return sm.comparator();} |
2158 } |
2158 } |
2159 |
2159 |
2160 public SortedMap<K,V> subMap(K fromKey, K toKey) { |
2160 public SortedMap<K,V> subMap(K fromKey, K toKey) { |
2161 synchronized(mutex) { |
2161 synchronized (mutex) { |
2162 return new SynchronizedSortedMap<K,V>( |
2162 return new SynchronizedSortedMap<K,V>( |
2163 sm.subMap(fromKey, toKey), mutex); |
2163 sm.subMap(fromKey, toKey), mutex); |
2164 } |
2164 } |
2165 } |
2165 } |
2166 public SortedMap<K,V> headMap(K toKey) { |
2166 public SortedMap<K,V> headMap(K toKey) { |
2167 synchronized(mutex) { |
2167 synchronized (mutex) { |
2168 return new SynchronizedSortedMap<K,V>(sm.headMap(toKey), mutex); |
2168 return new SynchronizedSortedMap<K,V>(sm.headMap(toKey), mutex); |
2169 } |
2169 } |
2170 } |
2170 } |
2171 public SortedMap<K,V> tailMap(K fromKey) { |
2171 public SortedMap<K,V> tailMap(K fromKey) { |
2172 synchronized(mutex) { |
2172 synchronized (mutex) { |
2173 return new SynchronizedSortedMap<K,V>(sm.tailMap(fromKey),mutex); |
2173 return new SynchronizedSortedMap<K,V>(sm.tailMap(fromKey),mutex); |
2174 } |
2174 } |
2175 } |
2175 } |
2176 |
2176 |
2177 public K firstKey() { |
2177 public K firstKey() { |
2178 synchronized(mutex) {return sm.firstKey();} |
2178 synchronized (mutex) {return sm.firstKey();} |
2179 } |
2179 } |
2180 public K lastKey() { |
2180 public K lastKey() { |
2181 synchronized(mutex) {return sm.lastKey();} |
2181 synchronized (mutex) {return sm.lastKey();} |
2182 } |
2182 } |
2183 } |
2183 } |
2184 |
2184 |
2185 // Dynamically typesafe collection wrappers |
2185 // Dynamically typesafe collection wrappers |
2186 |
2186 |
3446 * |
3446 * |
3447 * @param n the number of elements in the returned list. |
3447 * @param n the number of elements in the returned list. |
3448 * @param o the element to appear repeatedly in the returned list. |
3448 * @param o the element to appear repeatedly in the returned list. |
3449 * @return an immutable list consisting of <tt>n</tt> copies of the |
3449 * @return an immutable list consisting of <tt>n</tt> copies of the |
3450 * specified object. |
3450 * specified object. |
3451 * @throws IllegalArgumentException if n < 0. |
3451 * @throws IllegalArgumentException if {@code n < 0} |
3452 * @see List#addAll(Collection) |
3452 * @see List#addAll(Collection) |
3453 * @see List#addAll(int, Collection) |
3453 * @see List#addAll(int, Collection) |
3454 */ |
3454 */ |
3455 public static <T> List<T> nCopies(int n, T o) { |
3455 public static <T> List<T> nCopies(int n, T o) { |
3456 if (n < 0) |
3456 if (n < 0) |