001    package jet.runtime;
002    
003    import java.util.Arrays;
004    import java.util.Collection;
005    import java.util.Iterator;
006    
007    public class CollectionToArray {
008        // Implementation copied from AbstractCollection
009    
010        public static Object[] toArray(Collection<?> collection) {
011            Object[] r = new Object[collection.size()];
012            Iterator<?> it = collection.iterator();
013            for (int i = 0; i < r.length; i++) {
014                if (! it.hasNext()) // fewer elements than expected
015                    return Arrays.copyOf(r, i);
016                r[i] = it.next();
017            }
018            return it.hasNext() ? finishToArray(r, it) : r;
019        }
020    
021        public static <T, E> T[] toArray(Collection<E> collection, T[] a) {
022            // Estimate size of array; be prepared to see more or fewer elements
023            int size = collection.size();
024            T[] r = a.length >= size ? a :
025                    (T[])java.lang.reflect.Array
026                            .newInstance(a.getClass().getComponentType(), size);
027            Iterator<E> it = collection.iterator();
028    
029            for (int i = 0; i < r.length; i++) {
030                if (! it.hasNext()) { // fewer elements than expected
031                    if (a != r)
032                        return Arrays.copyOf(r, i);
033                    r[i] = null; // null-terminate
034                    return r;
035                }
036                r[i] = (T)it.next();
037            }
038            return it.hasNext() ? finishToArray(r, it) : r;
039        }
040    
041        private static <T> T[] finishToArray(T[] r, Iterator<?> it) {
042            int i = r.length;
043            while (it.hasNext()) {
044                int cap = r.length;
045                if (i == cap) {
046                    int newCap = ((cap / 2) + 1) * 3;
047                    if (newCap <= cap) { // integer overflow
048                        if (cap == Integer.MAX_VALUE)
049                            throw new OutOfMemoryError
050                                    ("Required array size too large");
051                        newCap = Integer.MAX_VALUE;
052                    }
053                    r = Arrays.copyOf(r, newCap);
054                }
055                r[i++] = (T)it.next();
056            }
057            // trim if overallocated
058            return (i == r.length) ? r : Arrays.copyOf(r, i);
059        }
060    
061        private CollectionToArray() {
062        }
063    }