Home | History | Annotate | Download | only in util
      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 
     32 package org.jf.util;
     33 
     34 import com.google.common.base.Predicate;
     35 import com.google.common.collect.ImmutableSortedSet;
     36 import com.google.common.collect.Ordering;
     37 import com.google.common.primitives.Ints;
     38 
     39 import javax.annotation.Nonnull;
     40 import java.util.*;
     41 
     42 public 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             T element2;
     81             try {
     82                 element2 = elements2.next();
     83             } catch (NoSuchElementException ex) {
     84                 return 1;
     85             }
     86             int res = comparator.compare(element1, element2);
     87             if (res != 0) return res;
     88         }
     89         if (elements2.hasNext()) {
     90             return -1;
     91         }
     92         return 0;
     93     }
     94 
     95     public static <T extends Comparable<? super T>> int compareAsIterable(@Nonnull Iterable<? extends T> it1,
     96                                                                           @Nonnull Iterable<? extends T> it2) {
     97         Iterator<? extends T> elements2 = it2.iterator();
     98         for (T element1: it1) {
     99             T element2;
    100             try {
    101                 element2 = elements2.next();
    102             } catch (NoSuchElementException ex) {
    103                 return 1;
    104             }
    105             int res = element1.compareTo(element2);
    106             if (res != 0) return res;
    107         }
    108         if (elements2.hasNext()) {
    109             return -1;
    110         }
    111         return 0;
    112     }
    113 
    114     public static <T> int compareAsList(@Nonnull Comparator<? super T> elementComparator,
    115                                         @Nonnull Collection<? extends T> list1,
    116                                         @Nonnull Collection<? extends T> list2) {
    117         int res = Ints.compare(list1.size(), list2.size());
    118         if (res != 0) return res;
    119         Iterator<? extends T> elements2 = list2.iterator();
    120         for (T element1: list1) {
    121             res = elementComparator.compare(element1, elements2.next());
    122             if (res != 0) return res;
    123         }
    124         return 0;
    125     }
    126 
    127     @Nonnull
    128     public static <T> Comparator<Collection<? extends T>> listComparator(
    129             @Nonnull final Comparator<? super T> elementComparator) {
    130         return new Comparator<Collection<? extends T>>() {
    131             @Override
    132             public int compare(Collection<? extends T> list1, Collection<? extends T> list2) {
    133                 return compareAsList(elementComparator, list1, list2);
    134             }
    135         };
    136     }
    137 
    138     public static <T> boolean isNaturalSortedSet(@Nonnull Iterable<? extends T> it) {
    139         if (it instanceof SortedSet) {
    140             SortedSet<? extends T> sortedSet = (SortedSet<? extends T>)it;
    141             Comparator<?> comparator = sortedSet.comparator();
    142             return (comparator == null) || comparator.equals(Ordering.natural());
    143         }
    144         return false;
    145     }
    146 
    147     public static <T> boolean isSortedSet(@Nonnull Comparator<? extends T> elementComparator,
    148                                           @Nonnull Iterable<? extends T> it) {
    149         if (it instanceof SortedSet) {
    150             SortedSet<? extends T> sortedSet = (SortedSet<? extends T>)it;
    151             Comparator<?> comparator = sortedSet.comparator();
    152             if (comparator == null) {
    153                 return elementComparator.equals(Ordering.natural());
    154             }
    155             return elementComparator.equals(comparator);
    156         }
    157         return false;
    158     }
    159 
    160     @Nonnull
    161     private static <T> SortedSet<? extends T> toNaturalSortedSet(@Nonnull Collection<? extends T> collection) {
    162         if (isNaturalSortedSet(collection)) {
    163             return (SortedSet<? extends T>)collection;
    164         }
    165         return ImmutableSortedSet.copyOf(collection);
    166     }
    167 
    168     @Nonnull
    169     private static <T> SortedSet<? extends T> toSortedSet(@Nonnull Comparator<? super T> elementComparator,
    170                                                           @Nonnull Collection<? extends T> collection) {
    171         if (collection instanceof SortedSet) {
    172             SortedSet<? extends T> sortedSet = (SortedSet<? extends T>)collection;
    173             Comparator<?> comparator = sortedSet.comparator();
    174             if (comparator != null && comparator.equals(elementComparator)) {
    175                 return sortedSet;
    176             }
    177         }
    178         return ImmutableSortedSet.copyOf(elementComparator, collection);
    179     }
    180 
    181     @Nonnull
    182     public static <T> Comparator<Collection<? extends T>> setComparator(
    183             @Nonnull final Comparator<? super T> elementComparator) {
    184         return new Comparator<Collection<? extends T>>() {
    185             @Override
    186             public int compare(Collection<? extends T> list1, Collection<? extends T> list2) {
    187                 return compareAsSet(elementComparator, list1, list2);
    188             }
    189         };
    190     }
    191 
    192     public static <T extends Comparable<T>> int compareAsSet(@Nonnull Collection<? extends T> set1,
    193                                                              @Nonnull Collection<? extends T> set2) {
    194         int res = Ints.compare(set1.size(), set2.size());
    195         if (res != 0) return res;
    196 
    197         SortedSet<? extends T> sortedSet1 = toNaturalSortedSet(set1);
    198         SortedSet<? extends T> sortedSet2 = toNaturalSortedSet(set2);
    199 
    200         Iterator<? extends T> elements2 = set2.iterator();
    201         for (T element1: set1) {
    202             res = element1.compareTo(elements2.next());
    203             if (res != 0) return res;
    204         }
    205         return 0;
    206     }
    207 
    208     public static <T> int compareAsSet(@Nonnull Comparator<? super T> elementComparator,
    209                                        @Nonnull Collection<? extends T> list1,
    210                                        @Nonnull Collection<? extends T> list2) {
    211         int res = Ints.compare(list1.size(), list2.size());
    212         if (res != 0) return res;
    213 
    214         SortedSet<? extends T> set1 = toSortedSet(elementComparator, list1);
    215         SortedSet<? extends T> set2 = toSortedSet(elementComparator, list2);
    216 
    217         Iterator<? extends T> elements2 = set2.iterator();
    218         for (T element1: set1) {
    219             res = elementComparator.compare(element1, elements2.next());
    220             if (res != 0) return res;
    221         }
    222         return 0;
    223     }
    224 }
    225