• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

talsma-ict / misc-java-utils / #16

18 Mar 2025 10:38PM CUT coverage: 100.0%. Remained the same
#16

push

sjoerdtalsma
Fix missing class for coveralls plugin.

Signed-off-by: Sjoerd Talsma <sjoerdtalsma@users.noreply.github.com>

19 of 19 relevant lines covered (100.0%)

1.0 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

100.0
/src/main/java/nl/talsmasoftware/misc/utils/FirstLastComparator.java
1
/*
2
 * Copyright 2022-2025 Talsma ICT
3
 *
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
7
 *
8
 *        http://www.apache.org/licenses/LICENSE-2.0
9
 *
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.
15
 */
16
package nl.talsmasoftware.misc.utils;
17

18
import java.io.Serializable;
19
import java.util.ArrayList;
20
import java.util.Arrays;
21
import java.util.Collection;
22
import java.util.Comparator;
23
import java.util.List;
24
import java.util.Objects;
25

26
/**
27
 * Comparator to sort certain values first or last.
28
 *
29
 * <p>
30
 * For example:
31
 * <pre>{@code
32
 * public static final Comparator<String> ADJUSTED_ORDER =
33
 *     FirstLastComparator.compareLast(String.CASE_INSENSITIVE_ORDER, "Always last");
34
 * }</pre>
35
 * In the example above, {@code ADJUSTED_ORDER} will sort Strings case-insensitive
36
 * where {@code "Always last"} is always sorted last.
37
 *
38
 * @param <T> The type to be sorted.
39
 * @author Sjoerd Talsma
40
 */
41
public final class FirstLastComparator<T> implements Comparator<T>, Serializable {
42
    private final Comparator<T> delegate;
43

44
    private final boolean compareFirst;
45

46
    private final List<T> explicitValues;
47

48
    private FirstLastComparator(Comparator<T> delegate, boolean compareFirst, Collection<? extends T> explicitValues) {
1✔
49
        this.delegate = Objects.requireNonNull(delegate, "Delegate comparator is <null>.");
1✔
50
        this.compareFirst = compareFirst;
1✔
51
        this.explicitValues = new ArrayList<>(explicitValues);
1✔
52
    }
1✔
53

54
    /**
55
     * Sort a limited collection of values first, delegating main sorting to another comparator.
56
     *
57
     * @param delegate    The main sorting delegate for all 'other' values.
58
     * @param firstValues The values to be sorted first.
59
     * @param <T>         The type to be sorted.
60
     * @return A comparator sorting the given values first.
61
     */
62
    public static <T> Comparator<T> compareFirst(Comparator<T> delegate, Collection<? extends T> firstValues) {
63
        return new FirstLastComparator<>(delegate, true,
1✔
64
                Objects.requireNonNull(firstValues, "firstValues is <null>."));
1✔
65
    }
66

67
    /**
68
     * Sort one or more values first, delegating main sorting to another comparator.
69
     *
70
     * @param delegate    The main sorting delegate for all 'other' values.
71
     * @param firstValues The values to be sorted first.
72
     * @param <T>         The type to be sorted.
73
     * @return A comparator sorting the given values first.
74
     */
75
    @SafeVarargs
76
    public static <T> Comparator<T> compareFirst(Comparator<T> delegate, T... firstValues) {
77
        return compareFirst(delegate, firstValues != null ? Arrays.asList(firstValues) : null);
1✔
78
    }
79

80
    /**
81
     * Sort a limited collection of values last, delegating main sorting to another comparator.
82
     *
83
     * @param delegate   The main sorting delegate for all 'other' values.
84
     * @param lastValues The values to be sorted last.
85
     * @param <T>        The type to be sorted.
86
     * @return A comparator sorting the given values last.
87
     */
88
    public static <T> Comparator<T> compareLast(Comparator<T> delegate, Collection<? extends T> lastValues) {
89
        return new FirstLastComparator<>(delegate, false,
1✔
90
                Objects.requireNonNull(lastValues, "lastValues is <null>."));
1✔
91
    }
92

93
    /**
94
     * Sort one or more values last, delegating main sorting to another comparator.
95
     *
96
     * @param delegate   The main sorting delegate for all 'other' values.
97
     * @param lastValues The values to be sorted last.
98
     * @param <T>        The type to be sorted.
99
     * @return A comparator sorting the given values last.
100
     */
101
    @SafeVarargs
102
    public static <T> Comparator<T> compareLast(Comparator<T> delegate, T... lastValues) {
103
        return compareLast(delegate, lastValues != null ? Arrays.asList(lastValues) : null);
1✔
104
    }
105

106
    /**
107
     * Compare two objects.
108
     * <p>
109
     * Check whether the compared objects are in the limited set of specified values.
110
     * If this is the case, the corresponding object(s) is sorted either first or last,
111
     * depending on the used factory method ({@code compareFirst} vs. {@code compareLast}).<br>
112
     * If neither of the compared objects are explicitly sorted first or last,
113
     * the specified {@code delegate} Comparator is used.
114
     *
115
     * @param o1 the first object to be compared.
116
     * @param o2 the second object to be compared.
117
     * @return a negative integer, zero, or a positive integer
118
     * as the first argument is less than, equal to, or greater than the second.
119
     */
120
    @Override
121
    public int compare(T o1, T o2) {
122
        final int i1 = explicitValues.indexOf(o1);
1✔
123
        final int i2 = explicitValues.indexOf(o2);
1✔
124

125
        if (i1 < 0) {
1✔
126
            if (i2 < 0) return delegate.compare(o1, o2);
1✔
127
            else return compareFirst ? 1 : -1;
1✔
128
        } else if (i2 < 0) {
1✔
129
            return compareFirst ? -1 : 1;
1✔
130
        }
131
        // i1 >= 0 && i2 >= 0, return explicit values in the order they are specified.
132
        return i1 - i2;
1✔
133
    }
134
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc