OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Rev

Rev 132 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
17 ilm 1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
5
 *
6
 * The contents of this file are subject to the terms of the GNU General Public License Version 3
7
 * only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
8
 * copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
9
 * language governing permissions and limitations under the License.
10
 *
11
 * When distributing the software, include this License Header Notice in each file.
12
 */
13
 
14
 /*
15
 * Créé le 14 avr. 2005
16
 */
17
package org.openconcerto.utils;
18
 
19
import org.openconcerto.utils.cc.ITransformer;
20
 
20 ilm 21
import java.math.BigDecimal;
93 ilm 22
import java.util.Collection;
17 ilm 23
import java.util.Comparator;
93 ilm 24
import java.util.Iterator;
25
import java.util.LinkedHashMap;
17 ilm 26
import java.util.List;
27
 
28
/**
29
 * @author Sylvain CUAZ
30
 */
31
public class CompareUtils {
32
 
132 ilm 33
    static public final <A extends Comparable<A>, B extends Comparable<B>> int compare(final A a1, final B b1, final A a2, final B b2) {
34
        final int res = a1.compareTo(a2);
35
        if (res != 0)
36
            return res;
37
        return b1.compareTo(b2);
38
    }
39
 
40
    static public final <A extends Comparable<A>, B extends Comparable<B>, C extends Comparable<C>> int compare(final A a1, final B b1, final C c1, final A a2, final B b2, final C c2) {
41
        final int res = compare(a1, b1, a2, b2);
42
        if (res != 0)
43
            return res;
44
        return c1.compareTo(c2);
45
    }
46
 
47
    static public final <A extends Comparable<A>, B extends Comparable<B>, C extends Comparable<C>, D extends Comparable<D>> int compare(final A a1, final B b1, final C c1, final D d1, final A a2,
48
            final B b2, final C c2, final D d2) {
49
        final int res = compare(a1, b1, c1, a2, b2, c2);
50
        if (res != 0)
51
            return res;
52
        return d1.compareTo(d2);
53
    }
54
 
55
    static public final <A extends Comparable<A>, B extends Comparable<B>> int compare(final Tuple2<A, B> t1, final Tuple2<A, B> t2) {
56
        return compare(t1.get0(), t1.get1(), t2.get0(), t2.get1());
57
    }
58
 
59
    static public final <A extends Comparable<A>, B extends Comparable<B>, C extends Comparable<C>> int compare(final Tuple3<A, B, C> t1, final Tuple3<A, B, C> t2) {
60
        return compare(t1.get0(), t1.get1(), t1.get2(), t2.get0(), t2.get1(), t2.get2());
61
    }
62
 
17 ilm 63
    /**
64
     * Compare 2 nombres entier avec longValue().
65
     *
66
     * @param n1 le premier nombre.
67
     * @param n2 le deuxième nombre.
68
     * @return 0 si ==, >0 si n1>2.
69
     */
70
    public static final int compareIntNumbers(Number n1, Number n2) {
71
        return compareLong(n1.longValue(), n2.longValue());
72
    }
73
 
74
    static public final int compareInt(int int1, int int2) {
75
        if (int1 < int2)
76
            return -1;
77
        else if (int1 == int2)
78
            return 0;
79
        else
80
            return +1;
81
    }
82
 
83
    static public final int compareLong(long int1, long int2) {
84
        if (int1 < int2)
85
            return -1;
86
        else if (int1 == int2)
87
            return 0;
88
        else
89
            return +1;
90
    }
91
 
132 ilm 92
    static public final <T extends Comparable<T>> int compareList(final List<? extends T> l1, final List<? extends T> l2) {
93
        return compareList(l1, l2, CompareUtils.<T> naturalOrder(), true);
94
    }
95
 
96
    static public final <T> int compareList(final List<? extends T> l1, final List<? extends T> l2, final Comparator<? super T> comp, final boolean longerAfter) {
97
        if (l1 == l2)
98
            return 0;
99
 
100
        final Iterator<? extends T> iter1 = l1.iterator();
101
        final Iterator<? extends T> iter2 = l2.iterator();
102
        while (iter1.hasNext() && iter2.hasNext()) {
103
            final T t1 = iter1.next();
104
            final T t2 = iter2.next();
105
            final int res = comp.compare(t1, t2);
106
            if (res != 0)
107
                return res;
108
        }
109
        if (!iter1.hasNext() && !iter2.hasNext()) {
110
            return 0;
111
        } else if (iter1.hasNext()) {
112
            return longerAfter ? 1 : -1;
113
        } else {
114
            assert iter2.hasNext();
115
            return longerAfter ? -1 : 1;
116
        }
117
    }
118
 
119
    @SuppressWarnings("rawtypes")
120
    private static final Comparator LIST_COMPARATOR = new Comparator<List>() {
121
        @SuppressWarnings("unchecked")
122
        @Override
123
        public int compare(List l1, List l2) {
124
            return compareList(l1, l2);
125
        }
126
    };
127
 
128
    @SuppressWarnings("unchecked")
129
    static public final <T extends Comparable<T>> Comparator<List<T>> getListComparator() {
130
        return LIST_COMPARATOR;
131
    }
132
 
133
    static public final <T> Comparator<List<T>> createListComparator(final Comparator<? super T> comp, final boolean longerAfter) {
134
        return new Comparator<List<T>>() {
135
            @Override
136
            public int compare(List<T> o1, List<T> o2) {
137
                return compareList(o1, o2, comp, longerAfter);
138
            }
139
        };
140
    }
141
 
17 ilm 142
    /**
25 ilm 143
     * Compare two objects if they're numbers or comparable.
144
     *
145
     * @param o1 first object.
146
     * @param o2 second object.
147
     * @return a negative integer, zero, or a positive integer as o1 is less than, equal to, or
148
     *         greater than o2.
149
     * @throws ClassCastException if o1 is neither a {@link Number} nor a {@link Comparable}, or if
150
     *         o2's type prevents it from being compared to o1.
151
     * @throws NullPointerException if o1 or o2 is <code>null</code>.
152
     * @see Comparable#compareTo(Object)
153
     * @see NumberUtils#compare(Number, Number)
154
     */
155
    static public final int compare(final Object o1, final Object o2) throws ClassCastException {
156
        if (o1 == null || o2 == null)
157
            throw new NullPointerException();
158
        if (o1 instanceof Number && o2 instanceof Number) {
159
            return NumberUtils.compare((Number) o1, (Number) o2);
160
        } else {
161
            // see Arrays.mergeSort()
162
            @SuppressWarnings({ "rawtypes", "unchecked" })
163
            final int res = ((Comparable) o1).compareTo(o2);
164
            return res;
165
        }
166
    }
167
 
80 ilm 168
    static private final Comparator<Comparable<Object>> NATURAL_COMPARATOR = new Comparator<Comparable<Object>>() {
169
        @Override
170
        public int compare(Comparable<Object> o1, Comparable<Object> o2) {
171
            return o1.compareTo(o2);
172
        }
173
    };
174
 
175
    // added in Comparator in Java 8
176
    @SuppressWarnings("unchecked")
177
    static public final <T extends Comparable<? super T>> Comparator<T> naturalOrder() {
178
        return (Comparator<T>) NATURAL_COMPARATOR;
179
    }
180
 
25 ilm 181
    /**
17 ilm 182
     * Renvoie un comparateur qui utilise successivement la liste passée tant que les objets sont
183
     * égaux.
184
     *
185
     * @param comparators une liste de Comparator.
186
     * @return le Comparator demandé.
187
     * @param <T> type of comparator
188
     */
189
    static public final <T> Comparator<T> createComparator(final List<? extends Comparator<T>> comparators) {
190
        return new Comparator<T>() {
191
            public String toString() {
192
                return "CompareUtils comparator with " + comparators;
193
            }
194
 
195
            public int compare(T o1, T o2) {
196
                int result = 0;
197
                int i = 0;
198
                while (i < comparators.size() && result == 0) {
199
                    final Comparator<T> transf = comparators.get(i);
200
                    result = transf.compare(o1, o2);
201
                    i++;
202
                }
203
                return result;
204
            }
205
        };
206
    }
207
 
208
    /**
209
     * Compare 2 objets pouvant être <code>null</code>.
210
     *
211
     * @param o1 the first object, can be <code>null</code>.
212
     * @param o2 the second object, can be <code>null</code>.
213
     * @return <code>true</code> if both are <code>null</code> or if o1.equals(o2).
20 ilm 214
     * @see Object#equals(Object)
17 ilm 215
     */
216
    static public final boolean equals(Object o1, Object o2) {
217
        if (o1 == null && o2 == null)
218
            return true;
219
        if (o1 == null || o2 == null)
220
            return false;
221
        return o1.equals(o2);
222
    }
223
 
20 ilm 224
    /**
225
     * Compare 2 objets pouvant être <code>null</code> avec compareTo(). Useful since for some
226
     * classes equals() is more specific than compareTo()==0, e.g. {@link BigDecimal#equals(Object)}
227
     * doesn't compare the numeric value but instance variables (1E2 is not equal to 100 or 100.00).
228
     *
229
     * @param o1 the first object, can be <code>null</code>.
230
     * @param o2 the second object, can be <code>null</code>.
231
     * @return <code>true</code> if both are <code>null</code> or if o1.compareTo(o2) == 0.
232
     * @see Comparable#compareTo(Object)
233
     */
234
    static public final <T> boolean equalsWithCompareTo(Comparable<T> o1, T o2) {
235
        if (o1 == null && o2 == null)
236
            return true;
237
        if (o1 == null || o2 == null)
238
            return false;
239
        return o1.compareTo(o2) == 0;
240
    }
241
 
93 ilm 242
    /**
243
     * Compare 2 collections in order. Useful since for some classes even though there's an order
244
     * <code>equals()</code> ignores it (e.g. {@link LinkedHashMap#equals(Object)}).
245
     *
246
     * @param c1 the first object, can be <code>null</code>.
247
     * @param c2 the second object, can be <code>null</code>.
248
     * @return <code>true</code> if both are <code>null</code> or if all items in order are
249
     *         {@link #equals(Object, Object)}.
250
     */
251
    static public final boolean equalsUsingIterator(Collection<?> c1, Collection<?> c2) {
252
        if (c1 == null && c2 == null)
253
            return true;
254
        if (c1 == null || c2 == null)
255
            return false;
256
 
257
        final int size = c1.size();
258
        if (size != c2.size())
259
            return false;
260
        else if (size == 0)
261
            return true;
262
 
263
        final Iterator<?> iter1 = c1.iterator();
264
        final Iterator<?> iter2 = c2.iterator();
265
        while (iter1.hasNext()) {
266
            final Object o1 = iter1.next();
267
            final Object o2 = iter2.next();
268
            if (!equals(o1, o2))
269
                return false;
270
        }
271
        assert !iter1.hasNext() && !iter2.hasNext();
272
        return true;
273
    }
274
 
17 ilm 275
    static public interface Equalizer<T> {
276
        public boolean equals(T o1, T o2);
277
    }
278
 
41 ilm 279
    static public final Equalizer<Object> OBJECT_EQ = new Equalizer<Object>() {
280
        public boolean equals(Object o1, Object o2) {
281
            return CompareUtils.equals(o1, o2);
282
        }
283
    };
284
 
17 ilm 285
    static public final <T> boolean equals(List<T> l1, List<T> l2, Equalizer<? super T> comp) {
286
        return compare(l1, l2, comp, null) == null;
287
    }
288
 
289
    /**
290
     * Compare two lists using the provided comparator.
291
     *
292
     * @param <T> type of items
293
     * @param l1 the first list.
294
     * @param l2 the second list.
295
     * @param comp how to compare each item.
296
     * @param toString how to dispay items, can be <code>null</code>.
297
     * @return <code>null</code> if the two lists are equal, otherwise a String explaining the
298
     *         difference.
299
     */
300
    static public final <T> String compare(List<T> l1, List<T> l2, Equalizer<? super T> comp, final ITransformer<? super T, String> toString) {
301
        final int size = l1.size();
302
        if (size != l2.size())
303
            return "unequal size";
304
        for (int i = 0; i < size; i++) {
305
            final T o1 = l1.get(i);
306
            final T o2 = l2.get(i);
307
            if (!comp.equals(o1, o2)) {
308
                final String s1 = toString == null ? String.valueOf(o1) : toString.transformChecked(o1);
309
                final String s2 = toString == null ? String.valueOf(o2) : toString.transformChecked(o2);
310
                return "unequal at " + i + ": " + s1 + " != " + s2;
311
            }
312
        }
313
        return null;
314
    }
156 ilm 315
 
316
    static public final <T extends Comparable<? super T>> T min(final T o1, final T o2) {
317
        return o1.compareTo(o2) < 0 ? o1 : o2;
318
    }
319
 
320
    static public final <T extends Comparable<? super T>> T max(final T o1, final T o2) {
321
        return o1.compareTo(o2) < 0 ? o2 : o1;
322
    }
17 ilm 323
}