Skip to contentMethod: sorted(List)
1: /*
2: * *************************************************************************************************************************************************************
3: *
4: * TheseFoolishThings: Miscellaneous utilities
5: * http://tidalwave.it/projects/thesefoolishthings
6: *
7: * Copyright (C) 2009 - 2024 by Tidalwave s.a.s. (http://tidalwave.it)
8: *
9: * *************************************************************************************************************************************************************
10: *
11: * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
12: * You may obtain a copy of the License at
13: *
14: * http://www.apache.org/licenses/LICENSE-2.0
15: *
16: * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
17: * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
18: *
19: * *************************************************************************************************************************************************************
20: *
21: * git clone https://bitbucket.org/tidalwave/thesefoolishthings-src
22: * git clone https://github.com/tidalwave-it/thesefoolishthings-src
23: *
24: * *************************************************************************************************************************************************************
25: */
26: package it.tidalwave.util;
27:
28: import javax.annotation.Nonnull;
29: import java.util.ArrayList;
30: import java.util.Collection;
31: import java.util.Collections;
32: import java.util.Comparator;
33: import java.util.List;
34: import java.util.Optional;
35: import lombok.AccessLevel;
36: import lombok.NoArgsConstructor;
37: import static java.util.Collections.emptyList;
38:
39: /***************************************************************************************************************************************************************
40: *
41: * This class contains a bunch of utility methods for manipulating lists.
42: *
43: * @author Fabrizio Giudici
44: * @since 3.2-ALPHA-13
45: * @it.tidalwave.javadoc.stable
46: *
47: **************************************************************************************************************************************************************/
48: @NoArgsConstructor(access = AccessLevel.PRIVATE)
49: public final class CollectionUtils
50: {
51: /***********************************************************************************************************************************************************
52: * Appends a list to an object. The resulting list is mutable.
53: *
54: * @param <T> the type of list items
55: * @param list the list
56: * @param object the list to append
57: * @return the list with the appended object
58: *
59: * @it.tidalwave.javadoc.stable
60: **********************************************************************************************************************************************************/
61: @Nonnull
62: public static <T> List<T> concat (@Nonnull final List<? extends T> list, @Nonnull final T object)
63: {
64: final List<T> result = new ArrayList<>(list);
65: result.add(object);
66: return result;
67: }
68:
69: /***********************************************************************************************************************************************************
70: * Returns a concatenation of the given {@link Collection}s.
71: *
72: * @param <T> the static type
73: * @param collections the input collections
74: * @return the concatenation
75: *
76: * @it.tidalwave.javadoc.stable
77: **********************************************************************************************************************************************************/
78: @Nonnull @SafeVarargs
79: public static <T> List<T> concatAll (@Nonnull final Collection<? extends T>... collections)
80: {
81: final List<T> result = new ArrayList<>();
82:
83: for (final var collection : collections)
84: {
85: result.addAll(collection);
86: }
87:
88: return result;
89: }
90:
91: /***********************************************************************************************************************************************************
92: * Reverses a list. The resulting list is mutable.
93: *
94: * @param <T> the type of list items
95: * @param list the list
96: * @return the reversed list
97: *
98: * @it.tidalwave.javadoc.stable
99: **********************************************************************************************************************************************************/
100: @Nonnull
101: public static <T> List<T> reversed (@Nonnull final List<? extends T> list)
102: {
103: final List<T> result = new ArrayList<>(list);
104: Collections.reverse(result);
105: return result;
106: }
107:
108: /***********************************************************************************************************************************************************
109: * Sorts a list. The resulting list is mutable.
110: *
111: * @param <T> the type of list items
112: * @param list the list
113: * @return the sorted list
114: * @since 3.2-ALPHA-13
115: *
116: * @it.tidalwave.javadoc.stable
117: **********************************************************************************************************************************************************/
118: @Nonnull
119: public static <T extends Comparable<? super T>> List<T> sorted (@Nonnull final List<? extends T> list)
120: {
121: final var result = new ArrayList<T>(list);
122: Collections.sort(result);
123: return result;
124: }
125:
126: /***********************************************************************************************************************************************************
127: * Sorts a list with a given {@link Comparator}. The resulting list is mutable.
128: *
129: * @param <T> the type of list items
130: * @param list the list
131: * @param comparator the comparator
132: * @return the sorted list
133: * @since 3.2-ALPHA-13
134: *
135: * @it.tidalwave.javadoc.stable
136: **********************************************************************************************************************************************************/
137: @Nonnull
138: public static <T> List<T> sorted (@Nonnull final List<? extends T> list,
139: @Nonnull final Comparator<? super T> comparator)
140: {
141: final var result = new ArrayList<T>(list);
142: result.sort(comparator);
143: return result;
144: }
145:
146: /***********************************************************************************************************************************************************
147: * Returns the (optional) first element of a list.
148: *
149: * @param <T> the type of list items
150: * @param list the list
151: * @return the first element
152: *
153: * @it.tidalwave.javadoc.stable
154: **********************************************************************************************************************************************************/
155: @Nonnull
156: public static <T> Optional<T> optionalHead (@Nonnull final List<? extends T> list)
157: {
158: return list.isEmpty() ? Optional.empty() : Optional.of(list.get(0));
159: }
160:
161: /***********************************************************************************************************************************************************
162: * Returns the first element of a list.
163: *
164: * @param <T> the type of list items
165: * @param list the list (cannot be empty)
166: * @return the first element
167: * @throws IllegalArgumentException if the list is empty
168: *
169: * @it.tidalwave.javadoc.stable
170: **********************************************************************************************************************************************************/
171: @Nonnull
172: public static <T> T head (@Nonnull final List<? extends T> list)
173: {
174: if (list.isEmpty())
175: {
176: throw new IllegalArgumentException("List is empty");
177: }
178:
179: return list.get(0);
180: }
181:
182: /***********************************************************************************************************************************************************
183: * Returns the tail element of a list, that is a list without the first element. The tail of an empty list is an
184: * empty list. The resulting list is mutable.
185: *
186: * @param <T> the type of list items
187: * @param list the list
188: * @return the tail of the list
189: *
190: * @it.tidalwave.javadoc.stable
191: **********************************************************************************************************************************************************/
192: @Nonnull
193: public static <T> List<T> tail (@Nonnull final List<? extends T> list)
194: {
195: return new ArrayList<>(list.subList(1, list.size()));
196: }
197:
198: /***********************************************************************************************************************************************************
199: * Return a sublist of the original {@link List}, from the given {@code from} and {@code to} index (not included).
200: * If the {@code from} index is negative and/or the {@code to} index is lower than the {@code from} index or if an
201: * attempt is made to read before the start or past the end of the list, truncation silently occurs.
202: *
203: * @param <T> the static type
204: * @param list the original list
205: * @param from the first index (included)
206: * @param to the last index (excluded)
207: * @return the sublist
208: * @since 3.2-ALPHA-17
209: **********************************************************************************************************************************************************/
210: @Nonnull
211: public static <T> List<T> safeSubList (@Nonnull final List<? extends T> list, final int from, final int to)
212: {
213: final var safeFrom = Math.max(from, 0);
214: final var safeTo = Math.min(list.size(), to);
215: return (safeFrom >= safeTo) ? emptyList() : new ArrayList<>(list.subList(safeFrom, safeTo));
216: }
217:
218: /***********************************************************************************************************************************************************
219: * Splits a given {@link List} at a set of boundaries. Each boundary is the starting point of a sublist to be
220: * returned.
221: *
222: * @param <T> the static type
223: * @param list the original list
224: * @param boundaries the boundaries
225: * @return a list of sublists
226: * @since 3.2-ALPHA-17
227: **********************************************************************************************************************************************************/
228: @Nonnull
229: public static <T> List<List<T>> split (@Nonnull final List<? extends T> list, final int ... boundaries)
230: {
231: final var result = new ArrayList<List<T>>();
232:
233: for (var i = 0; i < boundaries.length - 1; i++)
234: {
235: result.add(safeSubList(list, boundaries[i], boundaries[i + 1]));
236: }
237:
238: return result;
239: }
240: }