2 * Copyright 2000-2015 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.util.containers;
18 import com.intellij.openapi.Disposable;
19 import com.intellij.openapi.util.*;
20 import com.intellij.openapi.util.text.StringUtil;
21 import com.intellij.util.*;
23 import org.jetbrains.annotations.Contract;
24 import org.jetbrains.annotations.NotNull;
25 import org.jetbrains.annotations.Nullable;
27 import java.lang.reflect.Array;
29 import java.util.HashMap;
30 import java.util.HashSet;
31 import java.util.LinkedHashMap;
32 import java.util.LinkedHashSet;
33 import java.util.concurrent.ConcurrentMap;
34 import java.util.concurrent.CopyOnWriteArrayList;
36 @SuppressWarnings({"UtilityClassWithoutPrivateConstructor", "MethodOverridesStaticMethodOfSuperclass"})
37 public class ContainerUtil extends ContainerUtilRt {
38 private static final int INSERTION_SORT_THRESHOLD = 10;
39 private static final int DEFAULT_CONCURRENCY_LEVEL = Math.min(16, Runtime.getRuntime().availableProcessors());
43 public static <T> T[] ar(@NotNull T... elements) {
49 public static <K, V> HashMap<K, V> newHashMap() {
50 return ContainerUtilRt.newHashMap();
55 public static <K, V> HashMap<K, V> newHashMap(@NotNull Map<K, V> map) {
56 return ContainerUtilRt.newHashMap(map);
61 public static <K, V> Map<K, V> newHashMap(@NotNull Pair<K, V> first, @NotNull Pair<K, V>... entries) {
62 return ContainerUtilRt.newHashMap(first, entries);
67 public static <K, V> Map<K, V> newHashMap(@NotNull List<K> keys, @NotNull List<V> values) {
68 return ContainerUtilRt.newHashMap(keys, values);
73 public static <K extends Comparable, V> TreeMap<K, V> newTreeMap() {
74 return ContainerUtilRt.newTreeMap();
79 public static <K extends Comparable, V> TreeMap<K, V> newTreeMap(@NotNull Map<K, V> map) {
80 return ContainerUtilRt.newTreeMap(map);
85 public static <K, V> LinkedHashMap<K, V> newLinkedHashMap() {
86 return ContainerUtilRt.newLinkedHashMap();
91 public static <K, V> LinkedHashMap<K, V> newLinkedHashMap(int capacity) {
92 return ContainerUtilRt.newLinkedHashMap(capacity);
97 public static <K, V> LinkedHashMap<K, V> newLinkedHashMap(@NotNull Map<K, V> map) {
98 return ContainerUtilRt.newLinkedHashMap(map);
103 public static <K, V> LinkedHashMap<K, V> newLinkedHashMap(@NotNull Pair<K, V> first, @NotNull Pair<K, V>... entries) {
104 return ContainerUtilRt.newLinkedHashMap(first, entries);
109 public static <K, V> THashMap<K, V> newTroveMap() {
110 return new THashMap<K, V>();
115 public static <K, V> THashMap<K, V> newTroveMap(@NotNull TObjectHashingStrategy<K> strategy) {
116 return new THashMap<K, V>(strategy);
121 public static <K extends Enum<K>, V> EnumMap<K, V> newEnumMap(@NotNull Class<K> keyType) {
122 return new EnumMap<K, V>(keyType);
125 @SuppressWarnings("unchecked")
128 public static <T> TObjectHashingStrategy<T> canonicalStrategy() {
129 return TObjectHashingStrategy.CANONICAL;
132 @SuppressWarnings("unchecked")
135 public static <T> TObjectHashingStrategy<T> identityStrategy() {
136 return TObjectHashingStrategy.IDENTITY;
141 public static <K, V> IdentityHashMap<K, V> newIdentityHashMap() {
142 return new IdentityHashMap<K, V>();
147 public static <T> LinkedList<T> newLinkedList() {
148 return ContainerUtilRt.newLinkedList();
153 public static <T> LinkedList<T> newLinkedList(@NotNull T... elements) {
154 return ContainerUtilRt.newLinkedList(elements);
159 public static <T> LinkedList<T> newLinkedList(@NotNull Iterable<? extends T> elements) {
160 return ContainerUtilRt.newLinkedList(elements);
165 public static <T> ArrayList<T> newArrayList() {
166 return ContainerUtilRt.newArrayList();
171 public static <E> ArrayList<E> newArrayList(@NotNull E... array) {
172 return ContainerUtilRt.newArrayList(array);
177 public static <E> ArrayList<E> newArrayList(@NotNull Iterable<? extends E> iterable) {
178 return ContainerUtilRt.newArrayList(iterable);
181 /** @deprecated Use {@link #newArrayListWithCapacity(int)} (to remove in IDEA 15) */
182 @SuppressWarnings("deprecation")
184 public static <T> ArrayList<T> newArrayListWithExpectedSize(int size) {
185 return ContainerUtilRt.newArrayListWithCapacity(size);
190 public static <T> ArrayList<T> newArrayListWithCapacity(int size) {
191 return ContainerUtilRt.newArrayListWithCapacity(size);
196 public static <T> List<T> newArrayList(@NotNull final T[] elements, final int start, final int end) {
197 if (start < 0 || start > end || end > elements.length) {
198 throw new IllegalArgumentException("start:" + start + " end:" + end + " length:" + elements.length);
201 return new AbstractList<T>() {
202 private final int size = end - start;
205 public T get(final int index) {
206 if (index < 0 || index >= size) throw new IndexOutOfBoundsException("index:" + index + " size:" + size);
207 return elements[start + index];
219 public static <T> List<T> newSmartList() {
220 return new SmartList<T>();
225 public static <T> List<T> newSmartList(T element) {
226 return new SmartList<T>(element);
231 public static <T> List<T> newSmartList(@NotNull T... elements) {
232 return new SmartList<T>(elements);
237 public static <T> HashSet<T> newHashSet() {
238 return ContainerUtilRt.newHashSet();
243 public static <T> HashSet<T> newHashSet(int initialCapacity) {
244 return ContainerUtilRt.newHashSet(initialCapacity);
249 public static <T> HashSet<T> newHashSet(@NotNull T... elements) {
250 return ContainerUtilRt.newHashSet(elements);
255 public static <T> HashSet<T> newHashSet(@NotNull Iterable<? extends T> iterable) {
256 return ContainerUtilRt.newHashSet(iterable);
260 public static <T> HashSet<T> newHashSet(@NotNull Iterator<? extends T> iterator) {
261 return ContainerUtilRt.newHashSet(iterator);
266 public static <T> Set<T> newHashOrEmptySet(@Nullable Iterable<? extends T> iterable) {
267 boolean empty = iterable == null || iterable instanceof Collection && ((Collection)iterable).isEmpty();
268 return empty ? Collections.<T>emptySet() : ContainerUtilRt.newHashSet(iterable);
273 public static <T> LinkedHashSet<T> newLinkedHashSet() {
274 return ContainerUtilRt.newLinkedHashSet();
279 public static <T> LinkedHashSet<T> newLinkedHashSet(@NotNull Iterable<? extends T> elements) {
280 return ContainerUtilRt.newLinkedHashSet(elements);
285 public static <T> LinkedHashSet<T> newLinkedHashSet(@NotNull T... elements) {
286 return ContainerUtilRt.newLinkedHashSet(elements);
291 public static <T> THashSet<T> newTroveSet() {
292 return new THashSet<T>();
297 public static <T> THashSet<T> newTroveSet(@NotNull TObjectHashingStrategy<T> strategy) {
298 return new THashSet<T>(strategy);
303 public static <T> THashSet<T> newTroveSet(@NotNull T... elements) {
304 return newTroveSet(Arrays.asList(elements));
309 public static <T> THashSet<T> newTroveSet(@NotNull TObjectHashingStrategy<T> strategy, @NotNull T... elements) {
310 return new THashSet<T>(Arrays.asList(elements), strategy);
315 public static <T> THashSet<T> newTroveSet(@NotNull TObjectHashingStrategy<T> strategy, @NotNull Collection<T> elements) {
316 return new THashSet<T>(elements, strategy);
321 public static <T> THashSet<T> newTroveSet(@NotNull Collection<T> elements) {
322 return new THashSet<T>(elements);
327 public static <K> THashSet<K> newIdentityTroveSet() {
328 return new THashSet<K>(ContainerUtil.<K>identityStrategy());
333 public static <K> THashSet<K> newIdentityTroveSet(int initialCapacity) {
334 return new THashSet<K>(initialCapacity, ContainerUtil.<K>identityStrategy());
338 public static <K> THashSet<K> newIdentityTroveSet(@NotNull Collection<K> collection) {
339 return new THashSet<K>(collection, ContainerUtil.<K>identityStrategy());
344 public static <K,V> THashMap<K,V> newIdentityTroveMap() {
345 return new THashMap<K,V>(ContainerUtil.<K>identityStrategy());
350 public static <T> TreeSet<T> newTreeSet() {
351 return ContainerUtilRt.newTreeSet();
356 public static <T> TreeSet<T> newTreeSet(@NotNull Iterable<? extends T> elements) {
357 return ContainerUtilRt.newTreeSet(elements);
362 public static <T> TreeSet<T> newTreeSet(@NotNull T... elements) {
363 return ContainerUtilRt.newTreeSet(elements);
368 public static <T> TreeSet<T> newTreeSet(@Nullable Comparator<? super T> comparator) {
369 return ContainerUtilRt.newTreeSet(comparator);
374 public static <T> Set<T> newConcurrentSet() {
375 return new ConcurrentHashSet<T>();
380 public static <T> Set<T> newConcurrentSet(@NotNull TObjectHashingStrategy<T> hashStrategy) {
381 return new ConcurrentHashSet<T>(hashStrategy);
386 public static <K, V> ConcurrentMap<K, V> newConcurrentMap() {
387 return CHM_FACTORY.createMap();
391 public static <K, V> ConcurrentMap<K,V> newConcurrentMap(@NotNull TObjectHashingStrategy<K> hashStrategy) {
392 return CHM_FACTORY.createMap(hashStrategy);
396 public static <K, V> ConcurrentMap<K,V> newConcurrentMap(int initialCapacity) {
397 return CHM_FACTORY.createMap(initialCapacity);
401 public static <K, V> ConcurrentMap<K,V> newConcurrentMap(int initialCapacity, float loadFactor, int concurrencyLevel, @NotNull TObjectHashingStrategy<K> hashStrategy) {
402 return CHM_FACTORY.createMap(initialCapacity, loadFactor, concurrencyLevel, hashStrategy);
406 public static <K, V> ConcurrentMap<K,V> newConcurrentMap(int initialCapacity, float loadFactor, int concurrencyLevel) {
407 return CHM_FACTORY.createMap(initialCapacity, loadFactor, concurrencyLevel);
412 public static <E> List<E> reverse(@NotNull final List<E> elements) {
413 if (elements.isEmpty()) {
414 return ContainerUtilRt.emptyList();
417 return new AbstractList<E>() {
419 public E get(int index) {
420 return elements.get(elements.size() - 1 - index);
425 return elements.size();
432 public static <K, V> Map<K, V> union(@NotNull Map<? extends K, ? extends V> map, @NotNull Map<? extends K, ? extends V> map2) {
433 Map<K, V> result = new THashMap<K, V>(map.size() + map2.size());
441 public static <T> Set<T> union(@NotNull Set<T> set, @NotNull Set<T> set2) {
442 Set<T> result = new THashSet<T>(set.size() + set2.size());
450 public static <E> Set<E> immutableSet(@NotNull E ... elements) {
451 return Collections.unmodifiableSet(new THashSet<E>(Arrays.asList(elements)));
456 public static <E> ImmutableList<E> immutableList(@NotNull E ... array) {
457 return new ImmutableListBackedByArray<E>(array);
462 public static <E> ImmutableList<E> immutableList(@NotNull List<E> list) {
463 return new ImmutableListBackedByList<E>(list);
468 public static <K, V> ImmutableMapBuilder<K, V> immutableMapBuilder() {
469 return new ImmutableMapBuilder<K, V>();
472 public static class ImmutableMapBuilder<K, V> {
473 private final Map<K, V> myMap = new THashMap<K, V>();
475 public ImmutableMapBuilder<K, V> put(K key, V value) {
476 myMap.put(key, value);
481 public Map<K, V> build() {
482 return Collections.unmodifiableMap(myMap);
486 private static class ImmutableListBackedByList<E> extends ImmutableList<E> {
487 private final List<E> myStore;
489 private ImmutableListBackedByList(@NotNull List<E> list) {
494 public E get(int index) {
495 return myStore.get(index);
500 return myStore.size();
504 private static class ImmutableListBackedByArray<E> extends ImmutableList<E> {
505 private final E[] myStore;
507 private ImmutableListBackedByArray(@NotNull E[] array) {
512 public E get(int index) {
513 return myStore[index];
518 return myStore.length;
524 public static <K, V> Map<K, V> intersection(@NotNull Map<K, V> map1, @NotNull Map<K, V> map2) {
525 final Map<K, V> res = newHashMap();
526 final Set<K> keys = newHashSet();
527 keys.addAll(map1.keySet());
528 keys.addAll(map2.keySet());
532 if (v1 == v2 || v1 != null && v1.equals(v2)) {
541 public static <K, V> Map<K,Couple<V>> diff(@NotNull Map<K, V> map1, @NotNull Map<K, V> map2) {
542 final Map<K, Couple<V>> res = newHashMap();
543 final Set<K> keys = newHashSet();
544 keys.addAll(map1.keySet());
545 keys.addAll(map2.keySet());
549 if (!(v1 == v2 || v1 != null && v1.equals(v2))) {
550 res.put(k, Couple.of(v1, v2));
556 public static <T> boolean processSortedListsInOrder(@NotNull List<T> list1,
557 @NotNull List<T> list2,
558 @NotNull Comparator<? super T> comparator,
559 boolean mergeEqualItems,
560 @NotNull Processor<T> processor) {
563 while (index1 < list1.size() || index2 < list2.size()) {
565 if (index1 >= list1.size()) {
566 e = list2.get(index2++);
568 else if (index2 >= list2.size()) {
569 e = list1.get(index1++);
572 T element1 = list1.get(index1);
573 T element2 = list2.get(index2);
574 int c = comparator.compare(element1, element2);
583 if (c == 0 && !mergeEqualItems) {
584 if (!processor.process(e)) return false;
589 if (!processor.process(e)) return false;
597 public static <T> List<T> mergeSortedLists(@NotNull List<T> list1,
598 @NotNull List<T> list2,
599 @NotNull Comparator<? super T> comparator,
600 boolean mergeEqualItems) {
601 final List<T> result = new ArrayList<T>(list1.size() + list2.size());
602 processSortedListsInOrder(list1, list2, comparator, mergeEqualItems, new Processor<T>() {
604 public boolean process(T t) {
614 public static <T> List<T> mergeSortedArrays(@NotNull T[] list1, @NotNull T[] list2, @NotNull Comparator<? super T> comparator, boolean mergeEqualItems, @Nullable Processor<? super T> filter) {
617 List<T> result = new ArrayList<T>(list1.length + list2.length);
619 while (index1 < list1.length || index2 < list2.length) {
620 if (index1 >= list1.length) {
621 T t = list2[index2++];
622 if (filter != null && !filter.process(t)) continue;
625 else if (index2 >= list2.length) {
626 T t = list1[index1++];
627 if (filter != null && !filter.process(t)) continue;
631 T element1 = list1[index1];
632 if (filter != null && !filter.process(element1)) {
636 T element2 = list2[index2];
637 if (filter != null && !filter.process(element2)) {
641 int c = comparator.compare(element1, element2);
643 result.add(element1);
647 result.add(element2);
651 result.add(element1);
652 if (!mergeEqualItems) {
653 result.add(element2);
666 public static <T> List<T> subList(@NotNull List<T> list, int from) {
667 return list.subList(from, list.size());
670 public static <T> void addAll(@NotNull Collection<T> collection, @NotNull Iterable<? extends T> appendix) {
671 addAll(collection, appendix.iterator());
674 public static <T> void addAll(@NotNull Collection<T> collection, @NotNull Iterator<? extends T> iterator) {
675 while (iterator.hasNext()) {
676 T o = iterator.next();
682 * Adds all not-null elements from the {@code elements}, ignoring nulls
684 public static <T> void addAllNotNull(@NotNull Collection<T> collection, @NotNull Iterable<? extends T> elements) {
685 addAllNotNull(collection, elements.iterator());
689 * Adds all not-null elements from the {@code elements}, ignoring nulls
691 public static <T> void addAllNotNull(@NotNull Collection<T> collection, @NotNull Iterator<? extends T> elements) {
692 while (elements.hasNext()) {
693 T o = elements.next();
701 public static <T> List<T> collect(@NotNull Iterator<T> iterator) {
702 if (!iterator.hasNext()) return emptyList();
703 List<T> list = new ArrayList<T>();
704 addAll(list, iterator);
709 public static <T> Set<T> collectSet(@NotNull Iterator<T> iterator) {
710 if (!iterator.hasNext()) return Collections.emptySet();
711 Set<T> hashSet = newHashSet();
712 addAll(hashSet, iterator);
717 public static <K, V> Map<K, V> newMapFromKeys(@NotNull Iterator<K> keys, @NotNull Convertor<K, V> valueConvertor) {
718 Map<K, V> map = newHashMap();
719 while (keys.hasNext()) {
721 map.put(key, valueConvertor.convert(key));
727 public static <K, V> Map<K, V> newMapFromValues(@NotNull Iterator<V> values, @NotNull Convertor<V, K> keyConvertor) {
728 Map<K, V> map = newHashMap();
729 while (values.hasNext()) {
730 V value = values.next();
731 map.put(keyConvertor.convert(value), value);
737 public static <K, V> Map<K, Set<V>> classify(@NotNull Iterator<V> iterator, @NotNull Convertor<V, K> keyConvertor) {
738 Map<K, Set<V>> hashMap = new LinkedHashMap<K, Set<V>>();
739 while (iterator.hasNext()) {
740 V value = iterator.next();
741 final K key = keyConvertor.convert(value);
742 Set<V> set = hashMap.get(key);
744 hashMap.put(key, set = new LinkedHashSet<V>()); // ordered set!!
753 public static <T> Iterator<T> emptyIterator() {
754 return EmptyIterator.getInstance();
759 public static <T> Iterable<T> emptyIterable() {
760 return EmptyIterable.getInstance();
765 public static <T> T find(@NotNull T[] array, @NotNull Condition<T> condition) {
766 for (T element : array) {
767 if (condition.value(element)) return element;
772 public static <T> boolean process(@NotNull Iterable<? extends T> iterable, @NotNull Processor<T> processor) {
773 for (final T t : iterable) {
774 if (!processor.process(t)) {
781 public static <T> boolean process(@NotNull List<? extends T> list, @NotNull Processor<T> processor) {
782 //noinspection ForLoopReplaceableByForEach
783 for (int i = 0, size = list.size(); i < size; i++) {
785 if (!processor.process(t)) {
792 public static <T> boolean process(@NotNull T[] iterable, @NotNull Processor<? super T> processor) {
793 for (final T t : iterable) {
794 if (!processor.process(t)) {
801 public static <T> boolean process(@NotNull Iterator<T> iterator, @NotNull Processor<? super T> processor) {
802 while (iterator.hasNext()) {
803 if (!processor.process(iterator.next())) {
812 public static <T, V extends T> V find(@NotNull Iterable<V> iterable, @NotNull Condition<T> condition) {
813 return find(iterable.iterator(), condition);
818 public static <T> T find(@NotNull Iterable<? extends T> iterable, @NotNull final T equalTo) {
819 return find(iterable, new Condition<T>() {
821 public boolean value(final T object) {
822 return equalTo == object || equalTo.equals(object);
828 public static <T, V extends T> V find(@NotNull Iterator<V> iterator, @NotNull Condition<T> condition) {
829 while (iterator.hasNext()) {
830 V value = iterator.next();
831 if (condition.value(value)) return value;
838 public static <T, KEY, VALUE> Map<KEY, VALUE> map2Map(@NotNull T[] collection, @NotNull Function<T, Pair<KEY, VALUE>> mapper) {
839 return map2Map(Arrays.asList(collection), mapper);
844 public static <T, KEY, VALUE> Map<KEY, VALUE> map2Map(@NotNull Collection<? extends T> collection,
845 @NotNull Function<T, Pair<KEY, VALUE>> mapper) {
846 final Map<KEY, VALUE> set = new THashMap<KEY, VALUE>(collection.size());
847 for (T t : collection) {
848 Pair<KEY, VALUE> pair = mapper.fun(t);
849 set.put(pair.first, pair.second);
855 @Contract(pure = true)
856 public static <T, KEY, VALUE> Map<KEY, VALUE> map2MapNotNull(@NotNull T[] collection,
857 @NotNull Function<T, Pair<KEY, VALUE>> mapper) {
858 return map2MapNotNull(Arrays.asList(collection), mapper);
862 @Contract(pure = true)
863 public static <T, KEY, VALUE> Map<KEY, VALUE> map2MapNotNull(@NotNull Collection<? extends T> collection,
864 @NotNull Function<T, Pair<KEY, VALUE>> mapper) {
865 final Map<KEY, VALUE> set = new THashMap<KEY, VALUE>(collection.size());
866 for (T t : collection) {
867 Pair<KEY, VALUE> pair = mapper.fun(t);
869 set.put(pair.first, pair.second);
877 public static <KEY, VALUE> Map<KEY, VALUE> map2Map(@NotNull Collection<Pair<KEY, VALUE>> collection) {
878 final Map<KEY, VALUE> result = new THashMap<KEY, VALUE>(collection.size());
879 for (Pair<KEY, VALUE> pair : collection) {
880 result.put(pair.first, pair.second);
887 public static <T> Object[] map2Array(@NotNull T[] array, @NotNull Function<T, Object> mapper) {
888 return map2Array(array, Object.class, mapper);
893 public static <T> Object[] map2Array(@NotNull Collection<T> array, @NotNull Function<T, Object> mapper) {
894 return map2Array(array, Object.class, mapper);
899 public static <T, V> V[] map2Array(@NotNull T[] array, @NotNull Class<? super V> aClass, @NotNull Function<T, V> mapper) {
900 return map2Array(Arrays.asList(array), aClass, mapper);
905 public static <T, V> V[] map2Array(@NotNull Collection<? extends T> collection, @NotNull Class<? super V> aClass, @NotNull Function<T, V> mapper) {
906 final List<V> list = map2List(collection, mapper);
907 @SuppressWarnings("unchecked") V[] array = (V[])Array.newInstance(aClass, list.size());
908 return list.toArray(array);
913 public static <T, V> V[] map2Array(@NotNull Collection<? extends T> collection, @NotNull V[] to, @NotNull Function<T, V> mapper) {
914 return map2List(collection, mapper).toArray(to);
919 public static <T> List<T> filter(@NotNull T[] collection, @NotNull Condition<? super T> condition) {
920 return findAll(collection, condition);
925 public static int[] filter(@NotNull int[] collection, @NotNull TIntProcedure condition) {
926 TIntArrayList result = new TIntArrayList();
927 for (int t : collection) {
928 if (condition.execute(t)) {
932 return result.isEmpty() ? ArrayUtil.EMPTY_INT_ARRAY : result.toNativeArray();
937 public static <T> List<T> filter(@NotNull Condition<? super T> condition, @NotNull T... collection) {
938 return findAll(collection, condition);
943 public static <T> List<T> findAll(@NotNull T[] collection, @NotNull Condition<? super T> condition) {
944 final List<T> result = new SmartList<T>();
945 for (T t : collection) {
946 if (condition.value(t)) {
955 public static <T> List<T> filter(@NotNull Collection<? extends T> collection, @NotNull Condition<? super T> condition) {
956 return findAll(collection, condition);
960 @Contract(pure = true)
961 public static <K, V> Map<K, V> filter(@NotNull Map<K, ? extends V> map, @NotNull Condition<? super K> keyFilter) {
962 Map<K, V> result = newHashMap();
963 for (Map.Entry<K, ? extends V> entry : map.entrySet()) {
964 if (keyFilter.value(entry.getKey())) {
965 result.put(entry.getKey(), entry.getValue());
973 public static <T> List<T> findAll(@NotNull Collection<? extends T> collection, @NotNull Condition<? super T> condition) {
974 if (collection.isEmpty()) return emptyList();
975 final List<T> result = new SmartList<T>();
976 for (final T t : collection) {
977 if (condition.value(t)) {
986 public static <T> List<T> skipNulls(@NotNull Collection<? extends T> collection) {
987 return findAll(collection, Condition.NOT_NULL);
992 public static <T, V> List<V> findAll(@NotNull T[] collection, @NotNull Class<V> instanceOf) {
993 return findAll(Arrays.asList(collection), instanceOf);
998 public static <T, V> V[] findAllAsArray(@NotNull T[] collection, @NotNull Class<V> instanceOf) {
999 List<V> list = findAll(Arrays.asList(collection), instanceOf);
1000 @SuppressWarnings("unchecked") V[] array = (V[])Array.newInstance(instanceOf, list.size());
1001 return list.toArray(array);
1005 @Contract(pure=true)
1006 public static <T, V> V[] findAllAsArray(@NotNull Collection<? extends T> collection, @NotNull Class<V> instanceOf) {
1007 List<V> list = findAll(collection, instanceOf);
1008 @SuppressWarnings("unchecked") V[] array = (V[])Array.newInstance(instanceOf, list.size());
1009 return list.toArray(array);
1013 @Contract(pure=true)
1014 public static <T> T[] findAllAsArray(@NotNull T[] collection, @NotNull Condition<? super T> instanceOf) {
1015 List<T> list = findAll(collection, instanceOf);
1016 @SuppressWarnings("unchecked") T[] array = (T[])Array.newInstance(collection.getClass().getComponentType(), list.size());
1017 return list.toArray(array);
1021 @Contract(pure=true)
1022 public static <T, V> List<V> findAll(@NotNull Collection<? extends T> collection, @NotNull Class<V> instanceOf) {
1023 final List<V> result = new SmartList<V>();
1024 for (final T t : collection) {
1025 if (instanceOf.isInstance(t)) {
1026 @SuppressWarnings("unchecked") V v = (V)t;
1033 public static <T> void removeDuplicates(@NotNull Collection<T> collection) {
1034 Set<T> collected = newHashSet();
1035 for (Iterator<T> iterator = collection.iterator(); iterator.hasNext();) {
1036 T t = iterator.next();
1037 if (!collected.contains(t)) {
1047 @Contract(pure=true)
1048 public static Map<String, String> stringMap(@NotNull final String... keyValues) {
1049 final Map<String, String> result = newHashMap();
1050 for (int i = 0; i < keyValues.length - 1; i+=2) {
1051 result.put(keyValues[i], keyValues[i+1]);
1058 @Contract(pure=true)
1059 public static <T> Iterator<T> iterate(@NotNull T[] arrays) {
1060 return Arrays.asList(arrays).iterator();
1064 @Contract(pure=true)
1065 public static <T> Iterator<T> iterate(@NotNull final Enumeration<T> enumeration) {
1066 return new Iterator<T>() {
1068 public boolean hasNext() {
1069 return enumeration.hasMoreElements();
1074 return enumeration.nextElement();
1078 public void remove() {
1079 throw new UnsupportedOperationException();
1085 @Contract(pure=true)
1086 public static <T> Iterable<T> iterate(@NotNull T[] arrays, @NotNull Condition<? super T> condition) {
1087 return iterate(Arrays.asList(arrays), condition);
1091 @Contract(pure=true)
1092 public static <T> Iterable<T> iterate(@NotNull final Collection<? extends T> collection, @NotNull final Condition<? super T> condition) {
1093 if (collection.isEmpty()) return emptyIterable();
1094 return new Iterable<T>() {
1096 public Iterator<T> iterator() {
1097 return new Iterator<T>() {
1098 Iterator<? extends T> impl = collection.iterator();
1099 T next = findNext();
1102 public boolean hasNext() {
1103 return next != null;
1114 private T findNext() {
1115 while (impl.hasNext()) {
1116 T each = impl.next();
1117 if (condition.value(each)) {
1125 public void remove() {
1126 throw new UnsupportedOperationException();
1134 @Contract(pure=true)
1135 public static <T> Iterable<T> iterateBackward(@NotNull final List<? extends T> list) {
1136 return new Iterable<T>() {
1138 public Iterator<T> iterator() {
1139 return new Iterator<T>() {
1140 ListIterator<? extends T> it = list.listIterator(list.size());
1143 public boolean hasNext() {
1144 return it.hasPrevious();
1149 return it.previous();
1153 public void remove() {
1161 public static <E> void swapElements(@NotNull List<E> list, int index1, int index2) {
1162 E e1 = list.get(index1);
1163 E e2 = list.get(index2);
1164 list.set(index1, e2);
1165 list.set(index2, e1);
1169 public static <T> List<T> collect(@NotNull Iterator<?> iterator, @NotNull FilteringIterator.InstanceOf<T> instanceOf) {
1170 @SuppressWarnings("unchecked") List<T> list = collect(FilteringIterator.create((Iterator<T>)iterator, instanceOf));
1174 public static <T> void addAll(@NotNull Collection<T> collection, @NotNull Enumeration<? extends T> enumeration) {
1175 while (enumeration.hasMoreElements()) {
1176 T element = enumeration.nextElement();
1177 collection.add(element);
1182 public static <T, A extends T, C extends Collection<T>> C addAll(@NotNull C collection, @NotNull A... elements) {
1183 //noinspection ManualArrayToCollectionCopy
1184 for (T element : elements) {
1185 collection.add(element);
1191 * Adds all not-null elements from the {@code elements}, ignoring nulls
1194 public static <T, A extends T, C extends Collection<T>> C addAllNotNull(@NotNull C collection, @NotNull A... elements) {
1195 for (T element : elements) {
1196 if (element != null) {
1197 collection.add(element);
1203 public static <T> boolean removeAll(@NotNull Collection<T> collection, @NotNull T... elements) {
1204 boolean modified = false;
1205 for (T element : elements) {
1206 modified |= collection.remove(element);
1211 // returns true if the collection was modified
1212 public static <T> boolean retainAll(@NotNull Collection<T> collection, @NotNull Condition<? super T> condition) {
1213 boolean modified = false;
1215 for (Iterator<T> iterator = collection.iterator(); iterator.hasNext(); ) {
1216 T next = iterator.next();
1217 if (!condition.value(next)) {
1226 @Contract(pure=true)
1227 public static <T, U extends T> U findInstance(@NotNull Iterable<T> iterable, @NotNull Class<U> aClass) {
1228 return findInstance(iterable.iterator(), aClass);
1231 public static <T, U extends T> U findInstance(@NotNull Iterator<T> iterator, @NotNull Class<U> aClass) {
1232 //noinspection unchecked
1233 U u = (U)find(iterator, FilteringIterator.instanceOf(aClass));
1238 @Contract(pure=true)
1239 public static <T, U extends T> U findInstance(@NotNull T[] array, @NotNull Class<U> aClass) {
1240 return findInstance(Arrays.asList(array), aClass);
1244 @Contract(pure=true)
1245 public static <T, V> List<T> concat(@NotNull V[] array, @NotNull Function<V, Collection<? extends T>> fun) {
1246 return concat(Arrays.asList(array), fun);
1250 * @return read-only list consisting of the elements from the collections stored in list added together
1253 @Contract(pure=true)
1254 public static <T> List<T> concat(@NotNull Iterable<? extends Collection<T>> list) {
1255 List<T> result = new ArrayList<T>();
1256 for (final Collection<T> ts : list) {
1259 return result.isEmpty() ? Collections.<T>emptyList() : result;
1263 * @deprecated Use {@link #append(java.util.List, java.lang.Object[])} or {@link #prepend(java.util.List, java.lang.Object[])} instead
1264 * @param appendTail specify whether additional values should be appended in front or after the list
1265 * @return read-only list consisting of the elements from specified list with some additional values
1269 @Contract(pure=true)
1270 public static <T> List<T> concat(boolean appendTail, @NotNull List<? extends T> list, @NotNull T... values) {
1271 return appendTail ? concat(list, list(values)) : concat(list(values), list);
1275 @Contract(pure=true)
1276 public static <T> List<T> append(@NotNull List<? extends T> list, @NotNull T... values) {
1277 return concat(list, list(values));
1281 * prepend values in front of the list
1282 * @return read-only list consisting of values and the elements from specified list
1285 @Contract(pure=true)
1286 public static <T> List<T> prepend(@NotNull List<? extends T> list, @NotNull T... values) {
1287 return concat(list(values), list);
1291 * @return read-only list consisting of the two lists added together
1294 @Contract(pure=true)
1295 public static <T> List<T> concat(@NotNull final List<? extends T> list1, @NotNull final List<? extends T> list2) {
1296 if (list1.isEmpty() && list2.isEmpty()) {
1297 return Collections.emptyList();
1299 else if (list1.isEmpty()) {
1300 //noinspection unchecked
1301 return (List<T>)list2;
1303 else if (list2.isEmpty()) {
1304 //noinspection unchecked
1305 return (List<T>)list1;
1308 final int size1 = list1.size();
1309 final int size = size1 + list2.size();
1311 return new AbstractList<T>() {
1313 public T get(int index) {
1314 if (index < size1) {
1315 return list1.get(index);
1318 return list2.get(index - size1);
1329 @Contract(pure=true)
1330 public static <T> Iterable<T> concat(@NotNull final Iterable<? extends T>... iterables) {
1331 return new Iterable<T>() {
1333 public Iterator<T> iterator() {
1334 Iterator[] iterators = new Iterator[iterables.length];
1335 for (int i = 0; i < iterables.length; i++) {
1336 Iterable<? extends T> iterable = iterables[i];
1337 iterators[i] = iterable.iterator();
1339 @SuppressWarnings("unchecked") Iterator<T> i = concatIterators(iterators);
1346 @Contract(pure=true)
1347 public static <T> Iterator<T> concatIterators(@NotNull Iterator<T>... iterators) {
1348 return new SequenceIterator<T>(iterators);
1352 @Contract(pure=true)
1353 public static <T> Iterator<T> concatIterators(@NotNull Collection<Iterator<T>> iterators) {
1354 return new SequenceIterator<T>(iterators);
1358 @Contract(pure=true)
1359 public static <T> Iterable<T> concat(@NotNull final T[]... iterables) {
1360 return new Iterable<T>() {
1362 public Iterator<T> iterator() {
1363 Iterator[] iterators = new Iterator[iterables.length];
1364 for (int i = 0, iterablesLength = iterables.length; i < iterablesLength; i++) {
1365 T[] iterable = iterables[i];
1366 iterators[i] = Arrays.asList(iterable).iterator();
1368 @SuppressWarnings("unchecked") Iterator<T> i = concatIterators(iterators);
1375 * @return read-only list consisting of the lists added together
1378 @Contract(pure=true)
1379 public static <T> List<T> concat(@NotNull final List<? extends T>... lists) {
1381 for (List<? extends T> each : lists) {
1382 size += each.size();
1384 if (size == 0) return emptyList();
1385 final int finalSize = size;
1386 return new AbstractList<T>() {
1388 public T get(final int index) {
1389 if (index >= 0 && index < finalSize) {
1391 for (List<? extends T> each : lists) {
1392 if (from <= index && index < from + each.size()) return each.get(index - from);
1393 from += each.size();
1396 throw new IndexOutOfBoundsException("index: " + index + "size: " + size());
1407 * @return read-only list consisting of the lists added together
1410 @Contract(pure=true)
1411 public static <T> List<T> concat(@NotNull final List<List<? extends T>> lists) {
1412 @SuppressWarnings("unchecked") List<? extends T>[] array = lists.toArray(new List[lists.size()]);
1413 return concat(array);
1417 * @return read-only list consisting of the lists (made by listGenerator) added together
1420 @Contract(pure=true)
1421 public static <T, V> List<T> concat(@NotNull Iterable<? extends V> list, @NotNull Function<V, Collection<? extends T>> listGenerator) {
1422 List<T> result = new ArrayList<T>();
1423 for (final V v : list) {
1424 result.addAll(listGenerator.fun(v));
1426 return result.isEmpty() ? ContainerUtil.<T>emptyList() : result;
1429 @Contract(pure=true)
1430 public static <T> boolean intersects(@NotNull Collection<? extends T> collection1, @NotNull Collection<? extends T> collection2) {
1431 if (collection1.size() <= collection2.size()) {
1432 for (T t : collection1) {
1433 if (collection2.contains(t)) {
1439 for (T t : collection2) {
1440 if (collection1.contains(t)) {
1449 * @return read-only collection consisting of elements from both collections
1452 @Contract(pure=true)
1453 public static <T> Collection<T> intersection(@NotNull Collection<? extends T> collection1, @NotNull Collection<? extends T> collection2) {
1454 List<T> result = new ArrayList<T>();
1455 for (T t : collection1) {
1456 if (collection2.contains(t)) {
1460 return result.isEmpty() ? ContainerUtil.<T>emptyList() : result;
1464 @Contract(pure=true)
1465 public static <T> T getFirstItem(@Nullable Collection<T> items) {
1466 return getFirstItem(items, null);
1470 @Contract(pure=true)
1471 public static <T> T getFirstItem(@Nullable List<T> items) {
1472 return items == null || items.isEmpty() ? null : items.get(0);
1475 @Contract(pure=true)
1476 public static <T> T getFirstItem(@Nullable final Collection<T> items, @Nullable final T defaultResult) {
1477 return items == null || items.isEmpty() ? defaultResult : items.iterator().next();
1481 * The main difference from <code>subList</code> is that <code>getFirstItems</code> does not
1482 * throw any exceptions, even if maxItems is greater than size of the list
1485 * @param maxItems size of the result will be equal or less than <code>maxItems</code>
1486 * @param <T> type of list
1487 * @return new list with no more than <code>maxItems</code> first elements
1490 @Contract(pure=true)
1491 public static <T> List<T> getFirstItems(@NotNull final List<T> items, int maxItems) {
1492 return items.subList(0, Math.min(maxItems, items.size()));
1496 @Contract(pure=true)
1497 public static <T> T iterateAndGetLastItem(@NotNull Iterable<T> items) {
1498 Iterator<T> itr = items.iterator();
1500 while (itr.hasNext()) {
1508 @Contract(pure=true)
1509 public static <T, L extends List<T>> T getLastItem(@Nullable L list, @Nullable T def) {
1510 return isEmpty(list) ? def : list.get(list.size() - 1);
1514 @Contract(pure=true)
1515 public static <T, L extends List<T>> T getLastItem(@Nullable L list) {
1516 return getLastItem(list, null);
1520 * @return read-only collection consisting of elements from the 'from' collection which are absent from the 'what' collection
1523 @Contract(pure=true)
1524 public static <T> Collection<T> subtract(@NotNull Collection<T> from, @NotNull Collection<T> what) {
1525 final Set<T> set = newHashSet(from);
1526 set.removeAll(what);
1527 return set.isEmpty() ? ContainerUtil.<T>emptyList() : set;
1531 @Contract(pure=true)
1532 public static <T> T[] toArray(@Nullable Collection<T> c, @NotNull ArrayFactory<T> factory) {
1533 return c != null ? c.toArray(factory.create(c.size())) : factory.create(0);
1537 @Contract(pure=true)
1538 public static <T> T[] toArray(@NotNull Collection<? extends T> c1, @NotNull Collection<? extends T> c2, @NotNull ArrayFactory<T> factory) {
1539 return ArrayUtil.mergeCollections(c1, c2, factory);
1543 @Contract(pure=true)
1544 public static <T> T[] mergeCollectionsToArray(@NotNull Collection<? extends T> c1, @NotNull Collection<? extends T> c2, @NotNull ArrayFactory<T> factory) {
1545 return ArrayUtil.mergeCollections(c1, c2, factory);
1548 public static <T extends Comparable<T>> void sort(@NotNull List<T> list) {
1549 int size = list.size();
1551 if (size < 2) return;
1556 if (t0.compareTo(t1) > 0) {
1561 else if (size < INSERTION_SORT_THRESHOLD) {
1562 for (int i = 0; i < size; i++) {
1563 for (int j = 0; j < i; j++) {
1567 if (ti.compareTo(tj) < 0) {
1575 Collections.sort(list);
1579 public static <T> void sort(@NotNull List<T> list, @NotNull Comparator<? super T> comparator) {
1580 int size = list.size();
1582 if (size < 2) return;
1587 if (comparator.compare(t0, t1) > 0) {
1592 else if (size < INSERTION_SORT_THRESHOLD) {
1593 for (int i = 0; i < size; i++) {
1594 for (int j = 0; j < i; j++) {
1598 if (comparator.compare(ti, tj) < 0) {
1606 Collections.sort(list, comparator);
1610 public static <T extends Comparable<T>> void sort(@NotNull T[] a) {
1611 int size = a.length;
1613 if (size < 2) return;
1618 if (t0.compareTo(t1) > 0) {
1623 else if (size < INSERTION_SORT_THRESHOLD) {
1624 for (int i = 0; i < size; i++) {
1625 for (int j = 0; j < i; j++) {
1629 if (ti.compareTo(tj) < 0) {
1642 @Contract(pure=true)
1643 public static <T> List<T> sorted(@NotNull Collection<T> list, @NotNull Comparator<T> comparator) {
1644 return sorted((Iterable<T>)list, comparator);
1648 @Contract(pure=true)
1649 public static <T> List<T> sorted(@NotNull Iterable<T> list, @NotNull Comparator<T> comparator) {
1650 List<T> sorted = newArrayList(list);
1651 sort(sorted, comparator);
1656 @Contract(pure=true)
1657 public static <T extends Comparable<T>> List<T> sorted(@NotNull Collection<T> list) {
1658 return sorted(list, new Comparator<T>() {
1660 public int compare(T o1, T o2) {
1661 return o1.compareTo(o2);
1666 public static <T> void sort(@NotNull T[] a, @NotNull Comparator<T> comparator) {
1667 int size = a.length;
1669 if (size < 2) return;
1674 if (comparator.compare(t0, t1) > 0) {
1679 else if (size < INSERTION_SORT_THRESHOLD) {
1680 for (int i = 0; i < size; i++) {
1681 for (int j = 0; j < i; j++) {
1685 if (comparator.compare(ti, tj) < 0) {
1693 Arrays.sort(a, comparator);
1698 * @return read-only list consisting of the elements from the iterable converted by mapping
1701 @Contract(pure=true)
1702 public static <T,V> List<V> map(@NotNull Iterable<? extends T> iterable, @NotNull Function<T, V> mapping) {
1703 List<V> result = new ArrayList<V>();
1704 for (T t : iterable) {
1705 result.add(mapping.fun(t));
1707 return result.isEmpty() ? ContainerUtil.<V>emptyList() : result;
1711 * @return read-only list consisting of the elements from the iterable converted by mapping
1714 @Contract(pure=true)
1715 public static <T,V> List<V> map(@NotNull Collection<? extends T> iterable, @NotNull Function<T, V> mapping) {
1716 if (iterable.isEmpty()) return emptyList();
1717 List<V> result = new ArrayList<V>(iterable.size());
1718 for (T t : iterable) {
1719 result.add(mapping.fun(t));
1725 * @return read-only list consisting of the elements from the array converted by mapping with nulls filtered out
1728 @Contract(pure=true)
1729 public static <T, V> List<V> mapNotNull(@NotNull T[] array, @NotNull Function<T, V> mapping) {
1730 return mapNotNull(Arrays.asList(array), mapping);
1734 * @return read-only list consisting of the elements from the array converted by mapping with nulls filtered out
1737 @Contract(pure=true)
1738 public static <T, V> V[] mapNotNull(@NotNull T[] array, @NotNull Function<T, V> mapping, @NotNull V[] emptyArray) {
1739 List<V> result = new ArrayList<V>(array.length);
1741 V v = mapping.fun(t);
1746 if (result.isEmpty()) {
1747 assert emptyArray.length == 0 : "You must pass an empty array";
1750 return result.toArray(emptyArray);
1754 * @return read-only list consisting of the elements from the iterable converted by mapping with nulls filtered out
1757 @Contract(pure=true)
1758 public static <T, V> List<V> mapNotNull(@NotNull Iterable<? extends T> iterable, @NotNull Function<T, V> mapping) {
1759 List<V> result = new ArrayList<V>();
1760 for (T t : iterable) {
1761 final V o = mapping.fun(t);
1766 return result.isEmpty() ? ContainerUtil.<V>emptyList() : result;
1770 * @return read-only list consisting of the elements from the array converted by mapping with nulls filtered out
1773 @Contract(pure=true)
1774 public static <T, V> List<V> mapNotNull(@NotNull Collection<? extends T> iterable, @NotNull Function<T, V> mapping) {
1775 if (iterable.isEmpty()) {
1779 List<V> result = new ArrayList<V>(iterable.size());
1780 for (T t : iterable) {
1781 final V o = mapping.fun(t);
1786 return result.isEmpty() ? ContainerUtil.<V>emptyList() : result;
1790 * @return read-only list consisting of the elements with nulls filtered out
1793 @Contract(pure=true)
1794 public static <T> List<T> packNullables(@NotNull T... elements) {
1795 List<T> list = new ArrayList<T>();
1796 for (T element : elements) {
1797 addIfNotNull(element, list);
1799 return list.isEmpty() ? ContainerUtil.<T>emptyList() : list;
1803 * @return read-only list consisting of the elements from the array converted by mapping
1806 @Contract(pure=true)
1807 public static <T, V> List<V> map(@NotNull T[] array, @NotNull Function<T, V> mapping) {
1808 List<V> result = new ArrayList<V>(array.length);
1810 result.add(mapping.fun(t));
1812 return result.isEmpty() ? ContainerUtil.<V>emptyList() : result;
1816 @Contract(pure=true)
1817 public static <T, V> V[] map(@NotNull T[] arr, @NotNull Function<T, V> mapping, @NotNull V[] emptyArray) {
1818 if (arr.length==0) {
1819 assert emptyArray.length == 0 : "You must pass an empty array";
1823 List<V> result = new ArrayList<V>(arr.length);
1825 result.add(mapping.fun(t));
1827 return result.toArray(emptyArray);
1831 @Contract(pure=true)
1832 public static <T> Set<T> set(@NotNull T ... items) {
1833 return newHashSet(items);
1836 public static <K, V> void putIfNotNull(final K key, @Nullable V value, @NotNull final Map<K, V> result) {
1837 if (value != null) {
1838 result.put(key, value);
1842 public static <T> void add(final T element, @NotNull final Collection<T> result, @NotNull final Disposable parentDisposable) {
1843 if (result.add(element)) {
1844 Disposer.register(parentDisposable, new Disposable() {
1846 public void dispose() {
1847 result.remove(element);
1854 @Contract(pure=true)
1855 public static <T> List<T> createMaybeSingletonList(@Nullable T element) {
1856 return element == null ? ContainerUtil.<T>emptyList() : Collections.singletonList(element);
1860 @Contract(pure=true)
1861 public static <T> Set<T> createMaybeSingletonSet(@Nullable T element) {
1862 return element == null ? Collections.<T>emptySet() : Collections.singleton(element);
1866 public static <T, V> V getOrCreate(@NotNull Map<T, V> result, final T key, @NotNull V defaultValue) {
1867 V value = result.get(key);
1868 if (value == null) {
1869 result.put(key, value = defaultValue);
1874 public static <T, V> V getOrCreate(@NotNull Map<T, V> result, final T key, @NotNull Factory<V> factory) {
1875 V value = result.get(key);
1876 if (value == null) {
1877 result.put(key, value = factory.create());
1883 @Contract(pure=true)
1884 public static <T, V> V getOrElse(@NotNull Map<T, V> result, final T key, @NotNull V defValue) {
1885 V value = result.get(key);
1886 return value == null ? defValue : value;
1889 @Contract(pure=true)
1890 public static <T> boolean and(@NotNull T[] iterable, @NotNull Condition<T> condition) {
1891 return and(Arrays.asList(iterable), condition);
1894 @Contract(pure=true)
1895 public static <T> boolean and(@NotNull Iterable<T> iterable, @NotNull Condition<T> condition) {
1896 for (final T t : iterable) {
1897 if (!condition.value(t)) return false;
1902 @Contract(pure=true)
1903 public static <T> boolean exists(@NotNull T[] iterable, @NotNull Condition<T> condition) {
1904 return or(Arrays.asList(iterable), condition);
1907 @Contract(pure=true)
1908 public static <T> boolean exists(@NotNull Iterable<T> iterable, @NotNull Condition<T> condition) {
1909 return or(iterable, condition);
1912 @Contract(pure=true)
1913 public static <T> boolean or(@NotNull T[] iterable, @NotNull Condition<T> condition) {
1914 return or(Arrays.asList(iterable), condition);
1917 @Contract(pure=true)
1918 public static <T> boolean or(@NotNull Iterable<T> iterable, @NotNull Condition<T> condition) {
1919 for (final T t : iterable) {
1920 if (condition.value(t)) return true;
1926 @Contract(pure=true)
1927 public static <T> List<T> unfold(@Nullable T t, @NotNull NullableFunction<T, T> next) {
1928 if (t == null) return emptyList();
1930 List<T> list = new ArrayList<T>();
1939 @Contract(pure=true)
1940 public static <T> List<T> dropTail(@NotNull List<T> items) {
1941 return items.subList(0, items.size() - 1);
1945 @Contract(pure=true)
1946 public static <T> List<T> list(@NotNull T... items) {
1947 return Arrays.asList(items);
1950 // Generalized Quick Sort. Does neither array.clone() nor list.toArray()
1952 public static <T> void quickSort(@NotNull List<T> list, @NotNull Comparator<? super T> comparator) {
1953 quickSort(list, comparator, 0, list.size());
1956 private static <T> void quickSort(@NotNull List<T> x, @NotNull Comparator<? super T> comparator, int off, int len) {
1957 // Insertion sort on smallest arrays
1959 for (int i = off; i < len + off; i++) {
1960 for (int j = i; j > off && comparator.compare(x.get(j), x.get(j - 1)) < 0; j--) {
1961 swapElements(x, j, j - 1);
1967 // Choose a partition element, v
1968 int m = off + (len >> 1); // Small arrays, middle element
1971 int n = off + len - 1;
1972 if (len > 40) { // Big arrays, pseudomedian of 9
1974 l = med3(x, comparator, l, l + s, l + 2 * s);
1975 m = med3(x, comparator, m - s, m, m + s);
1976 n = med3(x, comparator, n - 2 * s, n - s, n);
1978 m = med3(x, comparator, l, m, n); // Mid-size, med of 3
1982 // Establish Invariant: v* (<v)* (>v)* v*
1985 int c = off + len - 1;
1988 while (b <= c && comparator.compare(x.get(b), v) <= 0) {
1989 if (comparator.compare(x.get(b), v) == 0) {
1990 swapElements(x, a++, b);
1994 while (c >= b && comparator.compare(v, x.get(c)) <= 0) {
1995 if (comparator.compare(x.get(c), v) == 0) {
1996 swapElements(x, c, d--);
2001 swapElements(x, b++, c--);
2004 // Swap partition elements back to middle
2006 int s = Math.min(a - off, b - a);
2007 vecswap(x, off, b - s, s);
2008 s = Math.min(d - c, n - d - 1);
2009 vecswap(x, b, n - s, s);
2011 // Recursively sort non-partition-elements
2012 if ((s = b - a) > 1) quickSort(x, comparator, off, s);
2013 if ((s = d - c) > 1) quickSort(x, comparator, n - s, s);
2017 * Returns the index of the median of the three indexed longs.
2019 private static <T> int med3(@NotNull List<T> x, Comparator<? super T> comparator, int a, int b, int c) {
2020 return comparator.compare(x.get(a), x.get(b)) < 0 ? comparator.compare(x.get(b), x.get(c)) < 0
2022 : comparator.compare(x.get(a), x.get(c)) < 0 ? c : a
2023 : comparator.compare(x.get(c), x.get(b)) < 0
2025 : comparator.compare(x.get(c), x.get(a)) < 0 ? c : a;
2029 * Swaps x[a .. (a+n-1)] with x[b .. (b+n-1)].
2031 private static <T> void vecswap(List<T> x, int a, int b, int n) {
2032 for (int i = 0; i < n; i++, a++, b++) {
2033 swapElements(x, a, b);
2038 * Merge sorted points, which are sorted by x and with equal x by y.
2039 * Result is put to x1 y1.
2041 public static void mergeSortedArrays(@NotNull TIntArrayList x1,
2042 @NotNull TIntArrayList y1,
2043 @NotNull TIntArrayList x2,
2044 @NotNull TIntArrayList y2) {
2045 TIntArrayList newX = new TIntArrayList();
2046 TIntArrayList newY = new TIntArrayList();
2051 while (i < x1.size() && j < x2.size()) {
2052 if (x1.get(i) < x2.get(j) || x1.get(i) == x2.get(j) && y1.get(i) < y2.get(j)) {
2053 newX.add(x1.get(i));
2054 newY.add(y1.get(i));
2057 else if (x1.get(i) > x2.get(j) || x1.get(i) == x2.get(j) && y1.get(i) > y2.get(j)) {
2058 newX.add(x2.get(j));
2059 newY.add(y2.get(j));
2063 newX.add(x1.get(i));
2064 newY.add(y1.get(i));
2070 while (i < x1.size()) {
2071 newX.add(x1.get(i));
2072 newY.add(y1.get(i));
2076 while (j < x2.size()) {
2077 newX.add(x2.get(j));
2078 newY.add(y2.get(j));
2084 x1.add(newX.toNativeArray());
2085 y1.add(newY.toNativeArray());
2090 * @return read-only set consisting of the only element o
2093 @Contract(pure=true)
2094 public static <T> Set<T> singleton(final T o, @NotNull final TObjectHashingStrategy<T> strategy) {
2095 return new SingletonSet<T>(o, strategy);
2099 * @return read-only list consisting of the elements from all of the collections
2102 @Contract(pure=true)
2103 public static <E> List<E> flatten(@NotNull Collection<E>[] collections) {
2104 return flatten(Arrays.asList(collections));
2108 * @return read-only list consisting of the elements from all of the collections
2111 @Contract(pure=true)
2112 public static <E> List<E> flatten(@NotNull Iterable<? extends Collection<E>> collections) {
2113 List<E> result = new ArrayList<E>();
2114 for (Collection<E> list : collections) {
2115 result.addAll(list);
2118 return result.isEmpty() ? ContainerUtil.<E>emptyList() : result;
2122 * @return read-only list consisting of the elements from all of the collections
2125 @Contract(pure=true)
2126 public static <E> List<E> flattenIterables(@NotNull Iterable<? extends Iterable<E>> collections) {
2127 List<E> result = new ArrayList<E>();
2128 for (Iterable<E> list : collections) {
2133 return result.isEmpty() ? ContainerUtil.<E>emptyList() : result;
2137 @Contract(pure=true)
2138 public static <K,V> V[] convert(@NotNull K[] from, @NotNull V[] to, @NotNull Function<K,V> fun) {
2139 if (to.length < from.length) {
2140 @SuppressWarnings("unchecked") V[] array = (V[])Array.newInstance(to.getClass().getComponentType(), from.length);
2143 for (int i = 0; i < from.length; i++) {
2144 to[i] = fun.fun(from[i]);
2149 @Contract(pure=true)
2150 public static <T> boolean containsIdentity(@NotNull Iterable<T> list, T element) {
2159 @Contract(pure=true)
2160 public static <T> int indexOfIdentity(@NotNull List<T> list, T element) {
2161 for (int i = 0, listSize = list.size(); i < listSize; i++) {
2162 if (list.get(i) == element) {
2169 @Contract(pure=true)
2170 public static <T> boolean equalsIdentity(@NotNull List<T> list1, @NotNull List<T> list2) {
2171 int listSize = list1.size();
2172 if (list2.size() != listSize) {
2176 for (int i = 0; i < listSize; i++) {
2177 if (list1.get(i) != list2.get(i)) {
2184 @Contract(pure=true)
2185 public static <T> int indexOf(@NotNull List<T> list, @NotNull Condition<T> condition) {
2186 for (int i = 0, listSize = list.size(); i < listSize; i++) {
2188 if (condition.value(t)) {
2195 @Contract(pure=true)
2196 public static <T> int lastIndexOf(@NotNull List<T> list, @NotNull Condition<T> condition) {
2197 for (int i = list.size() - 1; i >= 0; i--) {
2199 if (condition.value(t)) {
2207 @Contract(pure = true)
2208 public static <T, U extends T> U findLastInstance(@NotNull List<T> list, @NotNull final Class<U> clazz) {
2209 int i = lastIndexOf(list, new Condition<T>() {
2211 public boolean value(T t) {
2212 return clazz.isInstance(t);
2215 //noinspection unchecked
2216 return i < 0 ? null : (U)list.get(i);
2219 @Contract(pure=true)
2220 public static <T> int indexOf(@NotNull List<T> list, @NotNull final T object) {
2221 return indexOf(list, new Condition<T>() {
2223 public boolean value(T t) {
2224 return t.equals(object);
2230 @Contract(pure=true)
2231 public static <A,B> Map<B,A> reverseMap(@NotNull Map<A,B> map) {
2232 final Map<B,A> result = newHashMap();
2233 for (Map.Entry<A, B> entry : map.entrySet()) {
2234 result.put(entry.getValue(), entry.getKey());
2239 @Contract(pure=true)
2240 public static <T> boolean processRecursively(final T root, @NotNull PairProcessor<T, List<T>> processor) {
2241 final LinkedList<T> list = new LinkedList<T>();
2243 while (!list.isEmpty()) {
2244 final T o = list.removeFirst();
2245 if (!processor.process(o, list)) return false;
2251 public static <T> List<T> trimToSize(@Nullable List<T> list) {
2252 if (list == null) return null;
2253 if (list.isEmpty()) return emptyList();
2255 if (list instanceof ArrayList) {
2256 ((ArrayList)list).trimToSize();
2263 @Contract(pure=true)
2264 public static <T> Stack<T> newStack() {
2265 return ContainerUtilRt.newStack();
2269 @Contract(pure=true)
2270 public static <T> Stack<T> newStack(@NotNull Collection<T> initial) {
2271 return ContainerUtilRt.newStack(initial);
2275 @Contract(pure=true)
2276 public static <T> Stack<T> newStack(@NotNull T... initial) {
2277 return ContainerUtilRt.newStack(initial);
2281 @Contract(pure=true)
2282 public static <T> List<T> emptyList() {
2283 return ContainerUtilRt.emptyList();
2287 @Contract(pure=true)
2288 public static <T> CopyOnWriteArrayList<T> createEmptyCOWList() {
2289 return ContainerUtilRt.createEmptyCOWList();
2293 * Creates List which is thread-safe to modify and iterate.
2294 * It differs from the java.util.concurrent.CopyOnWriteArrayList in the following:
2295 * - faster modification in the uncontended case
2297 * - slower modification in highly contented case (which is the kind of situation you shouldn't use COWAL anyway)
2299 * N.B. Avoid using <code>list.toArray(new T[list.size()])</code> on this list because it is inherently racey and
2300 * therefore can return array with null elements at the end.
2303 @Contract(pure=true)
2304 public static <T> List<T> createLockFreeCopyOnWriteList() {
2305 return createConcurrentList();
2309 @Contract(pure=true)
2310 public static <T> List<T> createLockFreeCopyOnWriteList(@NotNull Collection<? extends T> c) {
2311 return new LockFreeCopyOnWriteArrayList<T>(c);
2315 @Contract(pure=true)
2316 public static <V> ConcurrentIntObjectMap<V> createConcurrentIntObjectMap() {
2317 //noinspection deprecation
2318 return new ConcurrentIntObjectHashMap<V>();
2322 @Contract(pure=true)
2323 public static <V> ConcurrentIntObjectMap<V> createConcurrentIntObjectSoftValueMap() {
2324 //noinspection deprecation
2325 return new ConcurrentSoftValueIntObjectHashMap<V>();
2329 @Contract(pure=true)
2330 public static <V> ConcurrentLongObjectMap<V> createConcurrentLongObjectMap() {
2331 //noinspection deprecation
2332 return new ConcurrentLongObjectHashMap<V>();
2336 @Contract(pure=true)
2337 public static <K,V> ConcurrentMap<K,V> createConcurrentWeakValueMap() {
2338 //noinspection deprecation
2339 return new ConcurrentWeakValueHashMap<K, V>();
2343 @Contract(pure=true)
2344 public static <V> ConcurrentIntObjectMap<V> createConcurrentIntObjectWeakValueMap() {
2345 //noinspection deprecation
2346 return new ConcurrentWeakValueIntObjectHashMap<V>();
2350 @Contract(pure=true)
2351 public static <K,V> ConcurrentMap<K,V> createConcurrentWeakKeySoftValueMap(int initialCapacity,
2353 int concurrencyLevel,
2354 @NotNull final TObjectHashingStrategy<K> hashingStrategy) {
2355 //noinspection deprecation
2356 return new ConcurrentWeakKeySoftValueHashMap<K, V>(initialCapacity, loadFactor, concurrencyLevel, hashingStrategy);
2360 @Contract(pure=true)
2361 public static <K,V> ConcurrentMap<K,V> createConcurrentSoftValueMap() {
2362 //noinspection deprecation
2363 return new ConcurrentSoftValueHashMap<K, V>();
2367 @Contract(pure=true)
2368 public static <K,V> ConcurrentMap<K,V> createConcurrentSoftMap() {
2369 //noinspection deprecation
2370 return new ConcurrentSoftHashMap<K, V>();
2374 @Contract(pure=true)
2375 public static <K,V> ConcurrentMap<K,V> createConcurrentWeakMap() {
2376 //noinspection deprecation
2377 return new ConcurrentWeakHashMap<K, V>();
2380 @Contract(pure=true)
2381 public static <K,V> ConcurrentMap<K,V> createConcurrentWeakMap(int initialCapacity,
2383 int concurrencyLevel,
2384 @NotNull TObjectHashingStrategy<K> hashingStrategy) {
2385 //noinspection deprecation
2386 return new ConcurrentWeakHashMap<K, V>(initialCapacity, loadFactor, concurrencyLevel, hashingStrategy);
2390 * @see {@link #createLockFreeCopyOnWriteList()}
2393 @Contract(pure=true)
2394 public static <T> ConcurrentList<T> createConcurrentList() {
2395 return new LockFreeCopyOnWriteArrayList<T>();
2398 public static <T> void addIfNotNull(@Nullable T element, @NotNull Collection<T> result) {
2399 ContainerUtilRt.addIfNotNull(element, result);
2402 public static <T> void addIfNotNull(@NotNull Collection<T> result, @Nullable T element) {
2403 ContainerUtilRt.addIfNotNull(result, element);
2407 @Contract(pure=true)
2408 public static <T, V> List<V> map2List(@NotNull T[] array, @NotNull Function<T, V> mapper) {
2409 return ContainerUtilRt.map2List(array, mapper);
2413 @Contract(pure=true)
2414 public static <T, V> List<V> map2List(@NotNull Collection<? extends T> collection, @NotNull Function<T, V> mapper) {
2415 return ContainerUtilRt.map2List(collection, mapper);
2419 @Contract(pure=true)
2420 public static <T, V> Set<V> map2Set(@NotNull T[] collection, @NotNull Function<T, V> mapper) {
2421 return ContainerUtilRt.map2Set(collection, mapper);
2425 @Contract(pure=true)
2426 public static <T, V> Set<V> map2Set(@NotNull Collection<? extends T> collection, @NotNull Function<T, V> mapper) {
2427 return ContainerUtilRt.map2Set(collection, mapper);
2431 @Contract(pure=true)
2432 public static <T, V> Set<V> map2SetNotNull(@NotNull Collection<? extends T> collection, @NotNull Function<T, V> mapper) {
2433 if (collection.isEmpty()) return Collections.emptySet();
2434 Set <V> set = new HashSet<V>(collection.size());
2435 for (T t : collection) {
2436 V value = mapper.fun(t);
2437 if (value != null) {
2441 return set.isEmpty() ? Collections.<V>emptySet() : set;
2445 @Contract(pure=true)
2446 public static <T> T[] toArray(@NotNull List<T> collection, @NotNull T[] array) {
2447 return ContainerUtilRt.toArray(collection, array);
2451 @Contract(pure=true)
2452 public static <T> T[] toArray(@NotNull Collection<T> c, @NotNull T[] sample) {
2453 return ContainerUtilRt.toArray(c, sample);
2457 public static <T> T[] copyAndClear(@NotNull Collection<T> collection, @NotNull ArrayFactory<T> factory, boolean clear) {
2458 int size = collection.size();
2459 T[] a = factory.create(size);
2461 a = collection.toArray(a);
2462 if (clear) collection.clear();
2468 @Contract(pure=true)
2469 public static <T> Collection<T> toCollection(@NotNull Iterable<T> iterable) {
2470 return iterable instanceof Collection ? (Collection<T>)iterable : newArrayList(iterable);
2474 public static <T> List<T> toList(@NotNull Enumeration<T> enumeration) {
2475 if (!enumeration.hasMoreElements()) {
2476 return Collections.emptyList();
2479 List<T> result = new SmartList<T>();
2480 while (enumeration.hasMoreElements()) {
2481 result.add(enumeration.nextElement());
2486 @Contract(value = "null -> true", pure = true)
2487 public static <T> boolean isEmpty(Collection<T> collection) {
2488 return collection == null || collection.isEmpty();
2492 @Contract(pure=true)
2493 public static <T> List<T> notNullize(@Nullable List<T> list) {
2494 return list == null ? ContainerUtilRt.<T>emptyList() : list;
2498 @Contract(pure=true)
2499 public static <T> Set<T> notNullize(@Nullable Set<T> set) {
2500 //noinspection unchecked
2501 return set == null ? Collections.<T>emptySet() : set;
2505 @Contract(pure=true)
2506 public static <T, C extends Collection<T>> C nullize(@Nullable C collection) {
2507 return isEmpty(collection) ? null : collection;
2510 private interface ConcurrentMapFactory {
2511 @NotNull <T, V> ConcurrentMap<T, V> createMap();
2512 @NotNull <T, V> ConcurrentMap<T, V> createMap(int initialCapacity);
2513 @NotNull <T, V> ConcurrentMap<T, V> createMap(@NotNull TObjectHashingStrategy<T> hashStrategy);
2514 @NotNull <T, V> ConcurrentMap<T, V> createMap(int initialCapacity, float loadFactor, int concurrencyLevel);
2515 @NotNull <T, V> ConcurrentMap<T, V> createMap(int initialCapacity, float loadFactor, int concurrencyLevel, @NotNull TObjectHashingStrategy<T> hashStrategy);
2518 private static final ConcurrentMapFactory V8_MAP_FACTORY = new ConcurrentMapFactory() {
2521 public <T, V> ConcurrentMap<T, V> createMap() {
2522 return new ConcurrentHashMap<T,V>();
2527 public <T, V> ConcurrentMap<T, V> createMap(int initialCapacity) {
2528 return new ConcurrentHashMap<T,V>(initialCapacity);
2533 public <T, V> ConcurrentMap<T, V> createMap(@NotNull TObjectHashingStrategy<T> hashStrategy) {
2534 return new ConcurrentHashMap<T,V>(hashStrategy);
2539 public <T, V> ConcurrentMap<T, V> createMap(int initialCapacity, float loadFactor, int concurrencyLevel) {
2540 return new ConcurrentHashMap<T,V>(initialCapacity, loadFactor, concurrencyLevel);
2545 public <T, V> ConcurrentMap<T, V> createMap(int initialCapacity, float loadFactor, int concurrencyLevel, @NotNull TObjectHashingStrategy<T> hashingStrategy) {
2546 return new ConcurrentHashMap<T,V>(initialCapacity, loadFactor, concurrencyLevel, hashingStrategy);
2550 private static final ConcurrentMapFactory PLATFORM_MAP_FACTORY = new ConcurrentMapFactory() {
2553 public <T, V> ConcurrentMap<T, V> createMap() {
2554 return createMap(16, 0.75f, DEFAULT_CONCURRENCY_LEVEL);
2559 public <T, V> ConcurrentMap<T, V> createMap(int initialCapacity) {
2560 return new java.util.concurrent.ConcurrentHashMap<T,V>(initialCapacity);
2565 public <T, V> ConcurrentMap<T, V> createMap(@NotNull TObjectHashingStrategy<T> hashingStrategy) {
2566 if (hashingStrategy != canonicalStrategy()) {
2567 throw new UnsupportedOperationException("Custom hashStrategy is not supported in java.util.concurrent.ConcurrentHashMap");
2569 // ignoring strategy parameter, because it is not supported by this implementation
2575 public <T, V> ConcurrentMap<T, V> createMap(int initialCapacity, float loadFactor, int concurrencyLevel) {
2576 return new java.util.concurrent.ConcurrentHashMap<T,V>(initialCapacity, loadFactor, concurrencyLevel);
2581 public <T, V> ConcurrentMap<T, V> createMap(int initialCapacity, float loadFactor, int concurrencyLevel, @NotNull TObjectHashingStrategy<T> hashingStrategy) {
2582 if (hashingStrategy != canonicalStrategy()) {
2583 throw new UnsupportedOperationException("Custom hashStrategy is not supported in java.util.concurrent.ConcurrentHashMap");
2585 // ignoring strategy parameter, because it is not supported by this implementation
2586 return createMap(initialCapacity, loadFactor, concurrencyLevel);
2590 private static final ConcurrentMapFactory CHM_FACTORY = SystemInfo.isOracleJvm || SystemInfo.isSunJvm || SystemInfo.isAppleJvm || isAtLeastJava7() ? V8_MAP_FACTORY : PLATFORM_MAP_FACTORY;
2592 private static boolean isAtLeastJava7() {
2593 // IBM JDK provides correct version in java.version property, but not in java.runtime.version property
2594 return StringUtil.compareVersionNumbers(SystemInfo.JAVA_VERSION, "1.7") >= 0;
2597 @Contract(pure=true)
2598 public static <T extends Comparable<T>> int compareLexicographically(@NotNull List<T> o1, @NotNull List<T> o2) {
2599 for (int i = 0; i < Math.min(o1.size(), o2.size()); i++) {
2600 int result = o1.get(i).compareTo(o2.get(i));
2605 return o1.size() < o2.size() ? -1 : o1.size() == o2.size() ? 0 : 1;
2608 @Contract(pure=true)
2609 public static <T> int compareLexicographically(@NotNull List<T> o1, @NotNull List<T> o2, @NotNull Comparator<T> comparator) {
2610 for (int i = 0; i < Math.min(o1.size(), o2.size()); i++) {
2611 int result = comparator.compare(o1.get(i), o2.get(i));
2616 return o1.size() < o2.size() ? -1 : o1.size() == o2.size() ? 0 : 1;
2620 * Returns a String representation of the given map, by listing all key-value pairs contained in the map.
2623 @Contract(pure = true)
2624 public static String toString(@NotNull Map<?, ?> map) {
2625 StringBuilder sb = new StringBuilder("{");
2626 for (Iterator<? extends Map.Entry<?, ?>> iterator = map.entrySet().iterator(); iterator.hasNext(); ) {
2627 Map.Entry<?, ?> entry = iterator.next();
2628 sb.append(entry.getKey()).append('=').append(entry.getValue());
2629 if (iterator.hasNext()) {
2634 return sb.toString();