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