CollectionUtils.java revision 4ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4
1/* 2 * Copyright 2012, Google Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * * Redistributions in binary form must reproduce the above 12 * copyright notice, this list of conditions and the following disclaimer 13 * in the documentation and/or other materials provided with the 14 * distribution. 15 * * Neither the name of Google Inc. nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32package org.jf.util; 33 34import com.google.common.base.Predicate; 35import com.google.common.collect.ImmutableSortedSet; 36import com.google.common.collect.Ordering; 37import com.google.common.primitives.Ints; 38 39import javax.annotation.Nonnull; 40import java.util.*; 41 42public class CollectionUtils { 43 public static <T> int listHashCode(@Nonnull Iterable<T> iterable) { 44 int hashCode = 1; 45 for (T item: iterable) { 46 hashCode = hashCode*31 + item.hashCode(); 47 } 48 return hashCode; 49 } 50 51 public static <T> int lastIndexOf(@Nonnull Iterable<T> iterable, @Nonnull Predicate<? super T> predicate) { 52 int index = 0; 53 int lastMatchingIndex = -1; 54 for (T item: iterable) { 55 if (predicate.apply(item)) { 56 lastMatchingIndex = index; 57 } 58 index++; 59 } 60 return lastMatchingIndex; 61 } 62 63 public static <T extends Comparable<? super T>> int compareAsList(@Nonnull Collection<? extends T> list1, 64 @Nonnull Collection<? extends T> list2) { 65 int res = Ints.compare(list1.size(), list2.size()); 66 if (res != 0) return res; 67 Iterator<? extends T> elements2 = list2.iterator(); 68 for (T element1: list1) { 69 res = element1.compareTo(elements2.next()); 70 if (res != 0) return res; 71 } 72 return 0; 73 } 74 75 public static <T> int compareAsIterable(@Nonnull Comparator<? super T> comparator, 76 @Nonnull Iterable<? extends T> it1, 77 @Nonnull Iterable<? extends T> it2) { 78 Iterator<? extends T> elements2 = it2.iterator(); 79 for (T element1: it1) { 80 int res = comparator.compare(element1, elements2.next()); 81 if (res != 0) return res; 82 } 83 return 0; 84 } 85 86 public static <T extends Comparable<? super T>> int compareAsIterable(@Nonnull Iterable<? extends T> it1, 87 @Nonnull Iterable<? extends T> it2) { 88 Iterator<? extends T> elements2 = it2.iterator(); 89 for (T element1: it1) { 90 int res = element1.compareTo(elements2.next()); 91 if (res != 0) return res; 92 } 93 return 0; 94 } 95 96 public static <T> int compareAsList(@Nonnull Comparator<? super T> elementComparator, 97 @Nonnull Collection<? extends T> list1, 98 @Nonnull Collection<? extends T> list2) { 99 int res = Ints.compare(list1.size(), list2.size()); 100 if (res != 0) return res; 101 Iterator<? extends T> elements2 = list2.iterator(); 102 for (T element1: list1) { 103 res = elementComparator.compare(element1, elements2.next()); 104 if (res != 0) return res; 105 } 106 return 0; 107 } 108 109 @Nonnull 110 public static <T> Comparator<Collection<? extends T>> listComparator( 111 @Nonnull final Comparator<? super T> elementComparator) { 112 return new Comparator<Collection<? extends T>>() { 113 @Override 114 public int compare(Collection<? extends T> list1, Collection<? extends T> list2) { 115 return compareAsList(elementComparator, list1, list2); 116 } 117 }; 118 } 119 120 public static <T> boolean isNaturalSortedSet(@Nonnull Iterable<? extends T> it) { 121 if (it instanceof SortedSet) { 122 SortedSet<? extends T> sortedSet = (SortedSet<? extends T>)it; 123 Comparator<?> comparator = sortedSet.comparator(); 124 return (comparator == null) || comparator.equals(Ordering.natural()); 125 } 126 return false; 127 } 128 129 public static <T> boolean isSortedSet(@Nonnull Comparator<? extends T> elementComparator, 130 @Nonnull Iterable<? extends T> it) { 131 if (it instanceof SortedSet) { 132 SortedSet<? extends T> sortedSet = (SortedSet<? extends T>)it; 133 Comparator<?> comparator = sortedSet.comparator(); 134 if (comparator == null) { 135 return elementComparator.equals(Ordering.natural()); 136 } 137 return elementComparator.equals(comparator); 138 } 139 return false; 140 } 141 142 @Nonnull 143 private static <T> SortedSet<? extends T> toNaturalSortedSet(@Nonnull Collection<? extends T> collection) { 144 if (isNaturalSortedSet(collection)) { 145 return (SortedSet<? extends T>)collection; 146 } 147 return ImmutableSortedSet.copyOf(collection); 148 } 149 150 @Nonnull 151 private static <T> SortedSet<? extends T> toSortedSet(@Nonnull Comparator<? super T> elementComparator, 152 @Nonnull Collection<? extends T> collection) { 153 if (collection instanceof SortedSet) { 154 SortedSet<? extends T> sortedSet = (SortedSet<? extends T>)collection; 155 Comparator<?> comparator = sortedSet.comparator(); 156 if (comparator != null && comparator.equals(elementComparator)) { 157 return sortedSet; 158 } 159 } 160 return ImmutableSortedSet.copyOf(elementComparator, collection); 161 } 162 163 @Nonnull 164 public static <T> Comparator<Collection<? extends T>> setComparator( 165 @Nonnull final Comparator<? super T> elementComparator) { 166 return new Comparator<Collection<? extends T>>() { 167 @Override 168 public int compare(Collection<? extends T> list1, Collection<? extends T> list2) { 169 return compareAsSet(elementComparator, list1, list2); 170 } 171 }; 172 } 173 174 public static <T extends Comparable<T>> int compareAsSet(@Nonnull Collection<? extends T> set1, 175 @Nonnull Collection<? extends T> set2) { 176 int res = Ints.compare(set1.size(), set2.size()); 177 if (res != 0) return res; 178 179 SortedSet<? extends T> sortedSet1 = toNaturalSortedSet(set1); 180 SortedSet<? extends T> sortedSet2 = toNaturalSortedSet(set2); 181 182 Iterator<? extends T> elements2 = set2.iterator(); 183 for (T element1: set1) { 184 res = element1.compareTo(elements2.next()); 185 if (res != 0) return res; 186 } 187 return 0; 188 } 189 190 public static <T> int compareAsSet(@Nonnull Comparator<? super T> elementComparator, 191 @Nonnull Collection<? extends T> list1, 192 @Nonnull Collection<? extends T> list2) { 193 int res = Ints.compare(list1.size(), list2.size()); 194 if (res != 0) return res; 195 196 SortedSet<? extends T> set1 = toSortedSet(elementComparator, list1); 197 SortedSet<? extends T> set2 = toSortedSet(elementComparator, list2); 198 199 Iterator<? extends T> elements2 = set2.iterator(); 200 for (T element1: set1) { 201 res = elementComparator.compare(element1, elements2.next()); 202 if (res != 0) return res; 203 } 204 return 0; 205 } 206} 207