1// © 2016 and later: Unicode, Inc. and others.
2// License & terms of use: http://www.unicode.org/copyright.html#License
3/*
4 ************************************************************************************
5 * Copyright (C) 2007-2015, Google Inc, International Business Machines Corporation
6 * and others. All Rights Reserved.
7 ************************************************************************************
8 */
9package com.ibm.icu.impl;
10
11import java.util.Comparator;
12import java.util.Iterator;
13
14/**
15 * TODO: Move to com.ibm.icu.dev.somewhere.
16 * 2015-sep-03: Not used in ICU but used in CLDR and in UnicodeTools.
17 */
18public class IterableComparator<T> implements Comparator<Iterable<T>> {
19    private final Comparator<T> comparator;
20    private final int shorterFirst; // = 1 for shorter first, -1 otherwise
21
22    public IterableComparator() {
23        this(null, true);
24    }
25
26    public IterableComparator(Comparator<T> comparator) {
27        this(comparator, true);
28    }
29
30    public IterableComparator(Comparator<T> comparator, boolean shorterFirst) {
31        this.comparator = comparator;
32        this.shorterFirst = shorterFirst ? 1 : -1;
33    }
34
35    @Override
36    public int compare(Iterable<T> a, Iterable<T> b) {
37        if (a == null) {
38            return b == null ? 0 : -shorterFirst;
39        } else if (b == null) {
40            return shorterFirst;
41        }
42        Iterator<T> ai = a.iterator();
43        Iterator<T> bi = b.iterator();
44        while (true) {
45            if (!ai.hasNext()) {
46                return bi.hasNext() ? -shorterFirst : 0;
47            }
48            if (!bi.hasNext()) {
49                return shorterFirst;
50            }
51            T aItem = ai.next();
52            T bItem = bi.next();
53            @SuppressWarnings("unchecked")
54            int result = comparator != null ? comparator.compare(aItem, bItem) : ((Comparable<T>)aItem).compareTo(bItem);
55            if (result != 0) {
56                return result;
57            }
58        }
59    }
60
61    @SuppressWarnings("unchecked")
62    public static <T> int compareIterables(Iterable<T> a, Iterable<T> b) {
63        return NOCOMPARATOR.compare(a, b);
64    }
65
66    @SuppressWarnings("rawtypes")
67    private static final IterableComparator NOCOMPARATOR = new IterableComparator();
68}