1 | package com.pivovarit.gatherers; | |
2 | ||
3 | import java.util.Iterator; | |
4 | import java.util.List; | |
5 | import java.util.Map; | |
6 | import java.util.Objects; | |
7 | import java.util.function.BiFunction; | |
8 | import java.util.function.BiPredicate; | |
9 | import java.util.function.Function; | |
10 | import java.util.stream.Collector; | |
11 | import java.util.stream.Collectors; | |
12 | import java.util.stream.Gatherer; | |
13 | import java.util.stream.Stream; | |
14 | ||
15 | /// Contains various [java.util.stream.Gatherer] implementations expanding [java.util.stream.Stream] API functionality | |
16 | public final class MoreGatherers { | |
17 | ||
18 | private MoreGatherers() { | |
19 | } | |
20 | ||
21 | /** | |
22 | * Creates a {@link Gatherer} that gathers the last {@code n} elements. | |
23 | * | |
24 | * @param <T> the type of the input elements | |
25 | * @param n the number of last elements to gather | |
26 | * | |
27 | * @return a {@link Gatherer} that collects the last {@code n} elements | |
28 | */ | |
29 | public static <T> Gatherer<T, ?, T> last(int n) { | |
30 |
1
1. last : replaced return value with null for com/pivovarit/gatherers/MoreGatherers::last → KILLED |
return LastGatherer.size(n); |
31 | } | |
32 | ||
33 | /** | |
34 | * Creates a {@link Gatherer} that gathers every {@code n}-th element. | |
35 | * | |
36 | * @param <T> the type of the input elements | |
37 | * @param n the interval at which elements are gathered | |
38 | * | |
39 | * @return a {@link Gatherer} that samples elements every {@code n}-th element | |
40 | */ | |
41 | public static <T> Gatherer<T, ?, T> sampling(int n) { | |
42 |
1
1. sampling : replaced return value with null for com/pivovarit/gatherers/MoreGatherers::sampling → KILLED |
return new SamplingGatherer<>(n); |
43 | } | |
44 | ||
45 | /** | |
46 | * Creates a {@link Gatherer} that filters elements to ensure that only distinct elements | |
47 | * remain, based on a key extracted by the given {@code keyExtractor}, keeping the last | |
48 | * occurrence of each distinct key. | |
49 | * | |
50 | * @param <T> the type of the input elements | |
51 | * @param <U> the type of the key extracted from the input elements | |
52 | * @param keyExtractor the function used to extract the key for distinguishing elements | |
53 | * | |
54 | * @return a {@link Gatherer} that collects distinct elements by key, keeping the last occurrence | |
55 | */ | |
56 | public static <T, U> Gatherer<T, ?, T> distinctByKeepLast(Function<? super T, ? extends U> keyExtractor) { | |
57 |
1
1. distinctByKeepLast : replaced return value with null for com/pivovarit/gatherers/MoreGatherers::distinctByKeepLast → KILLED |
return new DistinctByKeepLastGatherer<>(keyExtractor); |
58 | } | |
59 | ||
60 | /** | |
61 | * Creates a {@link Gatherer} that filters elements to ensure that only distinct elements | |
62 | * remain, based on a key extracted by the given {@code keyExtractor}, keeping the first | |
63 | * occurrence of each distinct key. | |
64 | * | |
65 | * @param <T> the type of the input elements | |
66 | * @param <U> the type of the key extracted from the input elements | |
67 | * @param keyExtractor the function used to extract the key for distinguishing elements | |
68 | * | |
69 | * @return a {@link Gatherer} that collects distinct elements by key, keeping the first occurrence | |
70 | */ | |
71 | public static <T, U> Gatherer<T, ?, T> distinctBy(Function<? super T, ? extends U> keyExtractor) { | |
72 |
1
1. distinctBy : replaced return value with null for com/pivovarit/gatherers/MoreGatherers::distinctBy → KILLED |
return new DistinctByGatherer<>(keyExtractor); |
73 | } | |
74 | ||
75 | /** | |
76 | * Creates a {@link Gatherer} that gathers distinct consecutive elements. | |
77 | * Elements are considered distinct if they are different from the previously gathered element. | |
78 | * | |
79 | * @param <T> the type of the input elements | |
80 | * | |
81 | * @return a {@link Gatherer} that collects distinct consecutive elements | |
82 | */ | |
83 | public static <T> Gatherer<T, ?, T> distinctUntilChanged() { | |
84 |
1
1. distinctUntilChanged : replaced return value with null for com/pivovarit/gatherers/MoreGatherers::distinctUntilChanged → KILLED |
return distinctUntilChanged(Function.identity()); |
85 | } | |
86 | ||
87 | /** | |
88 | * Creates a {@link Gatherer} that gathers distinct consecutive elements | |
89 | * based on a key extracted by the given {@code keyExtractor}. | |
90 | * Elements are considered distinct if the extracted key is different from the previous key. | |
91 | * | |
92 | * @param <T> the type of the input elements | |
93 | * @param <U> the type of the key extracted from the input elements | |
94 | * @param keyExtractor the function used to extract the key for distinguishing elements | |
95 | * | |
96 | * @return a {@link Gatherer} that collects distinct consecutive elements by key | |
97 | */ | |
98 | public static <T, U> Gatherer<T, ?, T> distinctUntilChanged(Function<? super T, ? extends U> keyExtractor) { | |
99 | Objects.requireNonNull(keyExtractor, "keyExtractor can't be null"); | |
100 |
1
1. distinctUntilChanged : replaced return value with null for com/pivovarit/gatherers/MoreGatherers::distinctUntilChanged → KILLED |
return new DistinctUntilChangedGatherer<>(keyExtractor); |
101 | } | |
102 | ||
103 | /** | |
104 | * Creates a {@link Gatherer} that zips elements of type {@code T1} with elements from | |
105 | * another {@link Stream} of type {@code T2}. The resulting pair is returned as a {@link Map.Entry}. | |
106 | * | |
107 | * @param <T1> the type of the first stream elements | |
108 | * @param <T2> the type of the second stream elements | |
109 | * @param other the other stream to zip with | |
110 | * | |
111 | * @return a {@link Gatherer} that pairs elements from the two streams | |
112 | */ | |
113 | public static <T1, T2> Gatherer<T1, ?, Map.Entry<T1, T2>> zip(Stream<T2> other) { | |
114 | Objects.requireNonNull(other, "other can't be null"); | |
115 |
1
1. zip : replaced return value with null for com/pivovarit/gatherers/MoreGatherers::zip → KILLED |
return zip(other.iterator()); |
116 | } | |
117 | ||
118 | /** | |
119 | * Creates a {@link Gatherer} that zips elements of type {@code T1} with elements from | |
120 | * another {@link Stream} of type {@code T2}, and combines them using the provided {@code mapper}. | |
121 | * | |
122 | * @param <T1> the type of the first stream elements | |
123 | * @param <T2> the type of the second stream elements | |
124 | * @param <R> the type of the result produced by the {@code mapper} | |
125 | * @param other the other stream to zip with | |
126 | * @param mapper the function that combines elements from both streams | |
127 | * | |
128 | * @return a {@link Gatherer} that pairs elements from the two streams using the {@code mapper} | |
129 | */ | |
130 | public static <T1, T2, R> Gatherer<T1, ?, R> zip(Stream<T2> other, BiFunction<? super T1, ? super T2, ? extends R> mapper) { | |
131 | Objects.requireNonNull(other, "other can't be null"); | |
132 |
1
1. zip : replaced return value with null for com/pivovarit/gatherers/MoreGatherers::zip → KILLED |
return zip(other.iterator(), mapper); |
133 | } | |
134 | ||
135 | /** | |
136 | * Creates a {@link Gatherer} that zips elements of type {@code T1} with elements from | |
137 | * another {@link Iterable} of type {@code T2}. The resulting pair is returned as a {@link Map.Entry}. | |
138 | * | |
139 | * @param <T1> the type of the first iterable elements | |
140 | * @param <T2> the type of the second iterable elements | |
141 | * @param other the other iterable to zip with | |
142 | * | |
143 | * @return a {@link Gatherer} that pairs elements from the two iterables | |
144 | */ | |
145 | public static <T1, T2> Gatherer<T1, ?, Map.Entry<T1, T2>> zipWithIterable(Iterable<T2> other) { | |
146 | Objects.requireNonNull(other, "other can't be null"); | |
147 |
1
1. zipWithIterable : replaced return value with null for com/pivovarit/gatherers/MoreGatherers::zipWithIterable → KILLED |
return zip(other.iterator()); |
148 | } | |
149 | ||
150 | /** | |
151 | * Creates a {@link Gatherer} that zips elements of type {@code T1} with elements from | |
152 | * another {@link Iterable} of type {@code T2}, and combines them using the provided {@code mapper}. | |
153 | * | |
154 | * @param <T1> the type of the first iterable elements | |
155 | * @param <T2> the type of the second iterable elements | |
156 | * @param <R> the type of the result produced by the {@code mapper} | |
157 | * @param other the other iterable to zip with | |
158 | * @param mapper the function that combines elements from both iterables | |
159 | * | |
160 | * @return a {@link Gatherer} that pairs elements from the two iterables using the {@code mapper} | |
161 | */ | |
162 | public static <T1, T2, R> Gatherer<T1, ?, R> zipWithIterable(Iterable<T2> other, BiFunction<? super T1, ? super T2, ? extends R> mapper) { | |
163 | Objects.requireNonNull(other, "other can't be null"); | |
164 | Objects.requireNonNull(mapper, "mapper can't be null"); | |
165 |
1
1. zipWithIterable : replaced return value with null for com/pivovarit/gatherers/MoreGatherers::zipWithIterable → KILLED |
return zip(other.iterator(), mapper); |
166 | } | |
167 | ||
168 | /** | |
169 | * Creates a {@link Gatherer} that zips elements of type {@code T1} with elements from | |
170 | * another {@link Iterator} of type {@code T2}. The resulting pair is returned as a {@link Map.Entry}. | |
171 | * | |
172 | * @param <T1> the type of the first iterator elements | |
173 | * @param <T2> the type of the second iterator elements | |
174 | * @param iterator the iterator to zip with | |
175 | * | |
176 | * @return a {@link Gatherer} that pairs elements from the two iterators | |
177 | */ | |
178 | public static <T1, T2> Gatherer<T1, ?, Map.Entry<T1, T2>> zip(Iterator<T2> iterator) { | |
179 |
1
1. zip : replaced return value with null for com/pivovarit/gatherers/MoreGatherers::zip → KILLED |
return zip(iterator, Map::entry); |
180 | } | |
181 | ||
182 | /** | |
183 | * Creates a {@link Gatherer} that zips elements of type {@code T1} with elements from | |
184 | * another {@link Iterator} of type {@code T2}, and combines them using the provided {@code mapper}. | |
185 | * | |
186 | * @param <T1> the type of the first iterator elements | |
187 | * @param <T2> the type of the second iterator elements | |
188 | * @param <R> the type of the result produced by the {@code mapper} | |
189 | * @param iterator the iterator to zip with | |
190 | * @param mapper the function that combines elements from both iterators | |
191 | * | |
192 | * @return a {@link Gatherer} that pairs elements from the two iterators using the {@code mapper} | |
193 | */ | |
194 | public static <T1, T2, R> Gatherer<T1, ?, R> zip(Iterator<T2> iterator, BiFunction<? super T1, ? super T2, ? extends R> mapper) { | |
195 |
1
1. zip : replaced return value with null for com/pivovarit/gatherers/MoreGatherers::zip → KILLED |
return new ZipIteratorGatherer<>(iterator, mapper); |
196 | } | |
197 | ||
198 | /** | |
199 | * Creates a {@link Gatherer} that zips elements with their corresponding index, | |
200 | * using the given {@code mapper} to produce the final result. | |
201 | * | |
202 | * @param <T> the type of the input elements | |
203 | * @param <R> the type of the result produced by the {@code mapper} | |
204 | * @param mapper the function that combines an index and an element to produce the result | |
205 | * | |
206 | * @return a {@link Gatherer} that pairs elements with their corresponding index using the {@code mapper} | |
207 | */ | |
208 | public static <T, R> Gatherer<T, ?, R> zipWithIndex(BiFunction<Long, ? super T, ? extends R> mapper) { | |
209 |
1
1. zipWithIndex : replaced return value with null for com/pivovarit/gatherers/MoreGatherers::zipWithIndex → KILLED |
return new ZipWithIndexMappingGatherer<>(mapper); |
210 | } | |
211 | ||
212 | /** | |
213 | * Creates a {@link Gatherer} that zips elements with their corresponding index, | |
214 | * producing a {@link Map.Entry} where the key is the index and the value is the element. | |
215 | * | |
216 | * @param <T> the type of the input elements | |
217 | * | |
218 | * @return a {@link Gatherer} that pairs elements with their corresponding index | |
219 | */ | |
220 | public static <T> Gatherer<T, ?, Map.Entry<T, Long>> zipWithIndex() { | |
221 |
1
1. zipWithIndex : replaced return value with null for com/pivovarit/gatherers/MoreGatherers::zipWithIndex → KILLED |
return new ZipWithIndexGatherer<>(); |
222 | } | |
223 | ||
224 | /** | |
225 | * Creates a {@link Gatherer} that collects elements into sliding windows of a specified size. | |
226 | * Each window captures a subset of elements from the input, and windows slide by a specified step. | |
227 | * <p> | |
228 | * This {@link Gatherer} extends {@link java.util.stream.Gatherers#windowSliding(int)} by allowing to customize the step | |
229 | * | |
230 | * <p>For example, if the window size is 3 and the step is 1, the gatherer will collect | |
231 | * windows of size 3, sliding by 1 element at a time. This means each subsequent window overlaps | |
232 | * with the previous one by two elements.</p> | |
233 | * | |
234 | * <p>Common use cases include moving averages, trend analysis, and any scenario requiring | |
235 | * overlapping or rolling window operations on a list of elements.</p> | |
236 | * | |
237 | * @param <T> the type of elements in the input and output list | |
238 | * @param windowSize the size of each window (must be a positive integer) | |
239 | * @param step the number of elements to slide the window by (must be a positive integer) | |
240 | * | |
241 | * @return a {@link Gatherer} that collects elements into sliding windows | |
242 | * | |
243 | * @throws IllegalArgumentException if {@code windowSize} is less than one or {@code step} is less than zero, or greater than {@code windowSize} | |
244 | */ | |
245 | public static <T> Gatherer<T, ?, List<T>> windowSliding(int windowSize, int step) { | |
246 |
1
1. windowSliding : replaced return value with null for com/pivovarit/gatherers/MoreGatherers::windowSliding → KILLED |
return new WindowSlidingGatherer<>(windowSize, step); |
247 | } | |
248 | ||
249 | /** | |
250 | * Creates a {@link Gatherer} that filters elements based on their index and value using a given {@link BiPredicate}. | |
251 | * The provided {@code BiPredicate} is applied to each element of the source, along with its corresponding index | |
252 | * (starting from 0). Only the elements that satisfy the predicate (i.e., for which the predicate returns {@code true}) | |
253 | * are retained. | |
254 | * <p> | |
255 | * The same result can be achieved by using {@code zipWithIndex()}, {@code filter()}, and {@code map()}. | |
256 | * However, this method is significantly faster because it avoids the intermediate steps and directly filters | |
257 | * elements based on their index. | |
258 | * | |
259 | * @param <T> the type of elements to be filtered | |
260 | * @param predicate a {@link BiPredicate} that takes the index and element as input, and returns {@code true} to retain | |
261 | * the element, or {@code false} to exclude it | |
262 | * | |
263 | * @return a {@link Gatherer} that applies the given filter based on element index and value | |
264 | */ | |
265 | public static <T> Gatherer<T, ?, T> filteringByIndex(BiPredicate<Long, ? super T> predicate) { | |
266 |
1
1. filteringByIndex : replaced return value with null for com/pivovarit/gatherers/MoreGatherers::filteringByIndex → KILLED |
return new FilterByIndexGatherer<>(predicate); |
267 | } | |
268 | ||
269 | /** | |
270 | * Creates a {@link Gatherer} that groups elements based on a key extracted by the given {@code classifier}. | |
271 | * | |
272 | * @param classifier the function used to extract the key for grouping elements | |
273 | * @param collector the {@link Collector} used to accumulate the elements of each group | |
274 | * @param <T> the type of the input elements | |
275 | * @param <K> the type of the key extracted from the input elements | |
276 | * @param <R> the type of the result of the collector | |
277 | * | |
278 | * @return a {@link Gatherer} that groups elements based on the extracted key | |
279 | */ | |
280 | public static <T, K, R> Gatherer<T, ?, Map.Entry<K, R>> groupingBy(Function<? super T, ? extends K> classifier, Collector<? super T, ?, ? extends R> collector) { | |
281 |
1
1. groupingBy : replaced return value with null for com/pivovarit/gatherers/MoreGatherers::groupingBy → KILLED |
return new GroupingByGatherer<>(classifier, collector); |
282 | } | |
283 | ||
284 | /** | |
285 | * Creates a {@link Gatherer} that groups elements based on a key extracted by the given {@code classifier}. | |
286 | * | |
287 | * @param classifier the function used to extract the key for grouping elements | |
288 | * @param <T> the type of the input elements | |
289 | * @param <K> the type of the key extracted from the input elements | |
290 | * | |
291 | * @return a {@link Gatherer} that groups elements based on the extracted key | |
292 | */ | |
293 | public static <T, K> Gatherer<T, ?, Map.Entry<K, List<T>>> groupingBy(Function<? super T, ? extends K> classifier) { | |
294 |
1
1. groupingBy : replaced return value with null for com/pivovarit/gatherers/MoreGatherers::groupingBy → KILLED |
return groupingBy(classifier, Collectors.toList()); |
295 | } | |
296 | } | |
Mutations | ||
30 |
1.1 |
|
42 |
1.1 |
|
57 |
1.1 |
|
72 |
1.1 |
|
84 |
1.1 |
|
100 |
1.1 |
|
115 |
1.1 |
|
132 |
1.1 |
|
147 |
1.1 |
|
165 |
1.1 |
|
179 |
1.1 |
|
195 |
1.1 |
|
209 |
1.1 |
|
221 |
1.1 |
|
246 |
1.1 |
|
266 |
1.1 |
|
281 |
1.1 |
|
294 |
1.1 |