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

javadev / underscore-java / #3107

pending completion
#3107

push

web-flow
Added com.github.underscore.XmlBuilder

4410 of 4410 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/com/github/underscore/Underscore.java
1
/*
2
 * The MIT License (MIT)
3
 *
4
 * Copyright 2015-2023 Valentyn Kolesnikov
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 */
24
package com.github.underscore;
25

26
import java.lang.reflect.Field;
27
import java.lang.reflect.Method;
28
import java.util.ArrayDeque;
29
import java.util.ArrayList;
30
import java.util.Arrays;
31
import java.util.Collection;
32
import java.util.Collections;
33
import java.util.Comparator;
34
import java.util.Date;
35
import java.util.Deque;
36
import java.util.HashMap;
37
import java.util.HashSet;
38
import java.util.Iterator;
39
import java.util.LinkedHashMap;
40
import java.util.LinkedHashSet;
41
import java.util.LinkedList;
42
import java.util.List;
43
import java.util.ListIterator;
44
import java.util.Map;
45
import java.util.Objects;
46
import java.util.Queue;
47
import java.util.Set;
48
import java.util.UUID;
49
import java.util.function.BiConsumer;
50
import java.util.function.BiFunction;
51
import java.util.function.BinaryOperator;
52
import java.util.function.Consumer;
53
import java.util.function.Function;
54
import java.util.function.Predicate;
55
import java.util.function.Supplier;
56
import java.util.function.UnaryOperator;
57

58
/**
59
 * Underscore-java is a java port of Underscore.js.
60
 *
61
 * @author Valentyn Kolesnikov
62
 */
63
@SuppressWarnings({"java:S106", "java:S2189", "java:S2272", "java:S3740", "java:S5852"})
64
public class Underscore<T> {
65
    private static final Map<String, Function<String, String>> FUNCTIONS = newLinkedHashMap();
1✔
66
    private static final Map<String, String> TEMPLATE_SETTINGS = new HashMap<>();
1✔
67
    private static final int MIN_PASSWORD_LENGTH_8 = 8;
68
    private static final long CAPACITY_SIZE_5 = 5L;
69
    private static final long CAPACITY_COEFF_2 = 2L;
70
    private static final long CAPACITY_SIZE_16 = 16L;
71
    private static final java.util.concurrent.atomic.AtomicInteger UNIQUE_ID =
1✔
72
            new java.util.concurrent.atomic.AtomicInteger(0);
73
    private static final String ALL_SYMBOLS = "([\\s\\S]+?)";
74
    private static final String EVALUATE = "evaluate";
75
    private static final String INTERPOLATE = "interpolate";
76
    private static final String ESCAPE = "escape";
77
    private static final String S_Q = "\\s*\\Q";
78
    private static final String E_S = "\\E\\s*";
79
    private static final java.util.regex.Pattern FORMAT_PATTERN =
1✔
80
            java.util.regex.Pattern.compile("\\{\\s*(\\d*)\\s*\\}");
1✔
81
    private static final Map<Character, String> ESCAPES = new HashMap<>();
1✔
82
    private final Iterable<T> iterable;
83
    private final Optional<String> string;
84

85
    static {
86
        TEMPLATE_SETTINGS.put(EVALUATE, "<%([\\s\\S]+?)%>");
1✔
87
        TEMPLATE_SETTINGS.put(INTERPOLATE, "<%=([\\s\\S]+?)%>");
1✔
88
        TEMPLATE_SETTINGS.put(ESCAPE, "<%-([\\s\\S]+?)%>");
1✔
89
        ESCAPES.put('&', "&amp;");
1✔
90
        ESCAPES.put('<', "&lt;");
1✔
91
        ESCAPES.put('>', "&gt;");
1✔
92
        ESCAPES.put('"', "&quot;");
1✔
93
        ESCAPES.put('\'', "&#x27;");
1✔
94
        ESCAPES.put('`', "&#x60;");
1✔
95
    }
1✔
96

97
    public Underscore(final Iterable<T> iterable) {
1✔
98
        this.iterable = iterable;
1✔
99
        this.string = Optional.empty();
1✔
100
    }
1✔
101

102
    public Underscore(final String string) {
1✔
103
        this.iterable = null;
1✔
104
        this.string = Optional.of(string);
1✔
105
    }
1✔
106

107
    private static void setTemplateKey(
108
            final Map<String, String> templateSettings, final String key) {
109
        if (templateSettings.containsKey(key) && templateSettings.get(key).contains(ALL_SYMBOLS)) {
1✔
110
            TEMPLATE_SETTINGS.put(key, templateSettings.get(key));
1✔
111
        }
112
    }
1✔
113

114
    public static void templateSettings(final Map<String, String> templateSettings) {
115
        setTemplateKey(templateSettings, EVALUATE);
1✔
116
        setTemplateKey(templateSettings, INTERPOLATE);
1✔
117
        setTemplateKey(templateSettings, ESCAPE);
1✔
118
    }
1✔
119

120
    private static final class WherePredicate<E, T> implements Predicate<E> {
121
        private final List<Map.Entry<String, T>> properties;
122

123
        private WherePredicate(List<Map.Entry<String, T>> properties) {
1✔
124
            this.properties = properties;
1✔
125
        }
1✔
126

127
        @Override
128
        public boolean test(final E elem) {
129
            for (Map.Entry<String, T> prop : properties) {
1✔
130
                try {
131
                    if (!elem.getClass()
1✔
132
                            .getField(prop.getKey())
1✔
133
                            .get(elem)
1✔
134
                            .equals(prop.getValue())) {
1✔
135
                        return false;
1✔
136
                    }
137
                } catch (Exception ex) {
1✔
138
                    try {
139
                        if (!elem.getClass()
1✔
140
                                .getMethod(prop.getKey())
1✔
141
                                .invoke(elem)
1✔
142
                                .equals(prop.getValue())) {
1✔
143
                            return false;
1✔
144
                        }
145
                    } catch (Exception ignored) {
1✔
146
                        // ignored
147
                    }
1✔
148
                }
1✔
149
            }
1✔
150
            return true;
1✔
151
        }
152
    }
153

154
    private static final class TemplateImpl<K, V> implements Template<Map<K, V>> {
155
        private final String template;
156

157
        private TemplateImpl(String template) {
1✔
158
            this.template = template;
1✔
159
        }
1✔
160

161
        @Override
162
        public String apply(Map<K, V> value) {
163
            final String evaluate = TEMPLATE_SETTINGS.get(EVALUATE);
1✔
164
            final String interpolate = TEMPLATE_SETTINGS.get(INTERPOLATE);
1✔
165
            final String escape = TEMPLATE_SETTINGS.get(ESCAPE);
1✔
166
            String result = template;
1✔
167
            for (final Map.Entry<K, V> element : value.entrySet()) {
1✔
168
                final String value1 =
1✔
169
                        String.valueOf(element.getValue())
1✔
170
                                .replace("\\", "\\\\")
1✔
171
                                .replace("$", "\\$");
1✔
172
                result =
1✔
173
                        java.util.regex.Pattern.compile(
1✔
174
                                        interpolate.replace(
1✔
175
                                                ALL_SYMBOLS, S_Q + element.getKey() + E_S))
1✔
176
                                .matcher(result)
1✔
177
                                .replaceAll(value1);
1✔
178
                result =
1✔
179
                        java.util.regex.Pattern.compile(
1✔
180
                                        escape.replace(ALL_SYMBOLS, S_Q + element.getKey() + E_S))
1✔
181
                                .matcher(result)
1✔
182
                                .replaceAll(escape(value1));
1✔
183
                result =
1✔
184
                        java.util.regex.Pattern.compile(
1✔
185
                                        evaluate.replace(ALL_SYMBOLS, S_Q + element.getKey() + E_S))
1✔
186
                                .matcher(result)
1✔
187
                                .replaceAll(value1);
1✔
188
            }
1✔
189
            return result;
1✔
190
        }
191

192
        @Override
193
        public List<String> check(Map<K, V> value) {
194
            final String evaluate = TEMPLATE_SETTINGS.get(EVALUATE);
1✔
195
            final String interpolate = TEMPLATE_SETTINGS.get(INTERPOLATE);
1✔
196
            final String escape = TEMPLATE_SETTINGS.get(ESCAPE);
1✔
197
            String result = template;
1✔
198
            final List<String> notFound = new ArrayList<>();
1✔
199
            final List<String> valueKeys = new ArrayList<>();
1✔
200
            for (final Map.Entry<K, V> element : value.entrySet()) {
1✔
201
                final String key = "" + element.getKey();
1✔
202
                java.util.regex.Matcher matcher =
1✔
203
                        java.util.regex.Pattern.compile(
1✔
204
                                        interpolate.replace(ALL_SYMBOLS, S_Q + key + E_S))
1✔
205
                                .matcher(result);
1✔
206
                boolean isFound = matcher.find();
1✔
207
                result = matcher.replaceAll(String.valueOf(element.getValue()));
1✔
208
                matcher =
1✔
209
                        java.util.regex.Pattern.compile(
1✔
210
                                        escape.replace(ALL_SYMBOLS, S_Q + key + E_S))
1✔
211
                                .matcher(result);
1✔
212
                isFound |= matcher.find();
1✔
213
                result = matcher.replaceAll(escape(String.valueOf(element.getValue())));
1✔
214
                matcher =
1✔
215
                        java.util.regex.Pattern.compile(
1✔
216
                                        evaluate.replace(ALL_SYMBOLS, S_Q + key + E_S))
1✔
217
                                .matcher(result);
1✔
218
                isFound |= matcher.find();
1✔
219
                result = matcher.replaceAll(String.valueOf(element.getValue()));
1✔
220
                if (!isFound) {
1✔
221
                    notFound.add(key);
1✔
222
                }
223
                valueKeys.add(key);
1✔
224
            }
1✔
225
            final List<String> templateVars = new ArrayList<>();
1✔
226
            java.util.regex.Matcher matcher =
1✔
227
                    java.util.regex.Pattern.compile(interpolate).matcher(result);
1✔
228
            while (matcher.find()) {
1✔
229
                templateVars.add(matcher.group(1).trim());
1✔
230
            }
231
            result = matcher.replaceAll("");
1✔
232
            matcher = java.util.regex.Pattern.compile(escape).matcher(result);
1✔
233
            while (matcher.find()) {
1✔
234
                templateVars.add(matcher.group(1).trim());
1✔
235
            }
236
            result = matcher.replaceAll("");
1✔
237
            matcher = java.util.regex.Pattern.compile(evaluate).matcher(result);
1✔
238
            while (matcher.find()) {
1✔
239
                templateVars.add(matcher.group(1).trim());
1✔
240
            }
241
            notFound.addAll(difference(templateVars, valueKeys));
1✔
242
            return notFound;
1✔
243
        }
244
    }
245

246
    private static final class MyIterable<T> implements Iterable<T> {
247
        private final UnaryOperator<T> unaryOperator;
248
        private boolean firstRun = true;
1✔
249
        private T value;
250

251
        MyIterable(final T seed, final UnaryOperator<T> unaryOperator) {
1✔
252
            this.value = seed;
1✔
253
            this.unaryOperator = unaryOperator;
1✔
254
        }
1✔
255

256
        public Iterator<T> iterator() {
257
            return new Iterator<>() {
1✔
258
                @Override
259
                public boolean hasNext() {
260
                    return true;
1✔
261
                }
262

263
                @Override
264
                public T next() {
265
                    if (firstRun) {
1✔
266
                        firstRun = false;
1✔
267
                    } else {
268
                        value = unaryOperator.apply(value);
1✔
269
                    }
270
                    return value;
1✔
271
                }
272

273
                @Override
274
                public void remove() {
275
                    // ignored
276
                }
1✔
277
            };
278
        }
279
    }
280

281
    public static <K, V> Function<Map<K, V>, V> iteratee(final K key) {
282
        return item -> item.get(key);
1✔
283
    }
284

285
    /*
286
     * Documented, #each
287
     */
288
    public static <T> void each(final Iterable<T> iterable, final Consumer<? super T> func) {
289
        for (T element : iterable) {
1✔
290
            func.accept(element);
1✔
291
        }
1✔
292
    }
1✔
293

294
    public static <T> void eachIndexed(
295
            final Iterable<T> iterable, final BiConsumer<Integer, ? super T> func) {
296
        int index = 0;
1✔
297
        for (T element : iterable) {
1✔
298
            func.accept(index, element);
1✔
299
            index += 1;
1✔
300
        }
1✔
301
    }
1✔
302

303
    public void each(final Consumer<? super T> func) {
304
        each(iterable, func);
1✔
305
    }
1✔
306

307
    public static <T> void eachRight(final Iterable<T> iterable, final Consumer<? super T> func) {
308
        each(reverse(iterable), func);
1✔
309
    }
1✔
310

311
    public void eachRight(final Consumer<? super T> func) {
312
        eachRight(iterable, func);
1✔
313
    }
1✔
314

315
    public static <T> void forEach(final Iterable<T> iterable, final Consumer<? super T> func) {
316
        each(iterable, func);
1✔
317
    }
1✔
318

319
    public static <T> void forEachIndexed(
320
            final Iterable<T> iterable, final BiConsumer<Integer, ? super T> func) {
321
        eachIndexed(iterable, func);
1✔
322
    }
1✔
323

324
    public void forEach(final Consumer<? super T> func) {
325
        each(iterable, func);
1✔
326
    }
1✔
327

328
    public void forEachIndexed(final BiConsumer<Integer, ? super T> func) {
329
        eachIndexed(iterable, func);
1✔
330
    }
1✔
331

332
    public static <T> void forEachRight(
333
            final Iterable<T> iterable, final Consumer<? super T> func) {
334
        eachRight(iterable, func);
1✔
335
    }
1✔
336

337
    public void forEachRight(final Consumer<? super T> func) {
338
        eachRight(iterable, func);
1✔
339
    }
1✔
340

341
    /*
342
     * Documented, #map
343
     */
344
    public static <T, E> List<T> map(final List<E> list, final Function<? super E, T> func) {
345
        final List<T> transformed = newArrayListWithExpectedSize(list.size());
1✔
346
        for (E element : list) {
1✔
347
            transformed.add(func.apply(element));
1✔
348
        }
1✔
349
        return transformed;
1✔
350
    }
351

352
    public static <T, E> List<T> mapMulti(
353
            final List<E> list, final BiConsumer<? super E, ? super Consumer<T>> mapper) {
354
        final List<T> transformed = newArrayListWithExpectedSize(list.size());
1✔
355
        for (E element : list) {
1✔
356
            Consumer<T> value = transformed::add;
1✔
357
            mapper.accept(element, value);
1✔
358
        }
1✔
359
        return transformed;
1✔
360
    }
361

362
    public <F> List<F> map(final Function<? super T, F> func) {
363
        return map(newArrayList(iterable), func);
1✔
364
    }
365

366
    public static <T> List<T> map(final int[] array, final Function<? super Integer, T> func) {
367
        final List<T> transformed = newArrayListWithExpectedSize(array.length);
1✔
368
        for (int element : array) {
1✔
369
            transformed.add(func.apply(element));
1✔
370
        }
371
        return transformed;
1✔
372
    }
373

374
    public static <T, E> Set<T> map(final Set<E> set, final Function<? super E, T> func) {
375
        final Set<T> transformed = newLinkedHashSetWithExpectedSize(set.size());
1✔
376
        for (E element : set) {
1✔
377
            transformed.add(func.apply(element));
1✔
378
        }
1✔
379
        return transformed;
1✔
380
    }
381

382
    public static <T, E> List<T> mapIndexed(
383
            final List<E> list, final BiFunction<Integer, ? super E, T> func) {
384
        final List<T> transformed = newArrayListWithExpectedSize(list.size());
1✔
385
        int index = 0;
1✔
386
        for (E element : list) {
1✔
387
            transformed.add(func.apply(index, element));
1✔
388
            index += 1;
1✔
389
        }
1✔
390
        return transformed;
1✔
391
    }
392

393
    public static <T> List<T> replace(
394
            final Iterable<T> iter, final Predicate<T> pred, final T value) {
395
        List<T> list = newArrayList(iter);
1✔
396
        if (pred == null) {
1✔
397
            return list;
1✔
398
        }
399
        ListIterator<T> itera = list.listIterator();
1✔
400
        while (itera.hasNext()) {
1✔
401
            if (pred.test(itera.next())) {
1✔
402
                itera.set(value);
1✔
403
            }
404
        }
405
        return list;
1✔
406
    }
407

408
    public List<T> replace(final Predicate<T> pred, final T value) {
409
        return replace(value(), pred, value);
1✔
410
    }
411

412
    public static <T> List<T> replaceIndexed(
413
            final Iterable<T> iter, final PredicateIndexed<T> pred, final T value) {
414
        List<T> list = newArrayList(iter);
1✔
415
        if (pred == null) {
1✔
416
            return list;
1✔
417
        }
418
        ListIterator<T> itera = list.listIterator();
1✔
419
        int index = 0;
1✔
420
        while (itera.hasNext()) {
1✔
421
            if (pred.test(index, itera.next())) {
1✔
422
                itera.set(value);
1✔
423
            }
424
            index++;
1✔
425
        }
426
        return list;
1✔
427
    }
428

429
    public List<T> replaceIndexed(final PredicateIndexed<T> pred, final T value) {
430
        return replaceIndexed(value(), pred, value);
1✔
431
    }
432

433
    public <F> List<F> mapIndexed(final BiFunction<Integer, ? super T, F> func) {
434
        return mapIndexed(newArrayList(iterable), func);
1✔
435
    }
436

437
    public static <T, E> List<T> collect(final List<E> list, final Function<? super E, T> func) {
438
        return map(list, func);
1✔
439
    }
440

441
    public static <T, E> Set<T> collect(final Set<E> set, final Function<? super E, T> func) {
442
        return map(set, func);
1✔
443
    }
444

445
    /*
446
     * Documented, #reduce
447
     */
448
    public static <T, E> E reduce(
449
            final Iterable<T> iterable, final BiFunction<E, T, E> func, final E zeroElem) {
450
        E accum = zeroElem;
1✔
451
        for (T element : iterable) {
1✔
452
            accum = func.apply(accum, element);
1✔
453
        }
1✔
454
        return accum;
1✔
455
    }
456

457
    public static <T> Optional<T> reduce(final Iterable<T> iterable, final BinaryOperator<T> func) {
458
        boolean foundAny = false;
1✔
459
        T accum = null;
1✔
460
        for (T element : iterable) {
1✔
461
            if (foundAny) {
1✔
462
                accum = func.apply(accum, element);
1✔
463
            } else {
464
                foundAny = true;
1✔
465
                accum = element;
1✔
466
            }
467
        }
1✔
468
        return foundAny ? Optional.of(accum) : Optional.empty();
1✔
469
    }
470

471
    public static <E> E reduce(
472
            final int[] array, final BiFunction<E, ? super Integer, E> func, final E zeroElem) {
473
        E accum = zeroElem;
1✔
474
        for (int element : array) {
1✔
475
            accum = func.apply(accum, element);
1✔
476
        }
477
        return accum;
1✔
478
    }
479

480
    public static <T, E> E reduce(
481
            final T[] array, final BiFunction<E, T, E> func, final E zeroElem) {
482
        E accum = zeroElem;
1✔
483
        for (T element : array) {
1✔
484
            accum = func.apply(accum, element);
1✔
485
        }
486
        return accum;
1✔
487
    }
488

489
    public static <T, E> E foldl(
490
            final Iterable<T> iterable, final BiFunction<E, T, E> func, final E zeroElem) {
491
        return reduce(iterable, func, zeroElem);
1✔
492
    }
493

494
    public static <T, E> E inject(
495
            final Iterable<T> iterable, final BiFunction<E, T, E> func, final E zeroElem) {
496
        return reduce(iterable, func, zeroElem);
1✔
497
    }
498

499
    /*
500
     * Documented, #reduceRight
501
     */
502
    public static <T, E> E reduceRight(
503
            final Iterable<T> iterable, final BiFunction<E, T, E> func, final E zeroElem) {
504
        return reduce(reverse(iterable), func, zeroElem);
1✔
505
    }
506

507
    public static <T> Optional<T> reduceRight(
508
            final Iterable<T> iterable, final BinaryOperator<T> func) {
509
        return reduce(reverse(iterable), func);
1✔
510
    }
511

512
    public static <E> E reduceRight(
513
            final int[] array, final BiFunction<E, ? super Integer, E> func, final E zeroElem) {
514
        E accum = zeroElem;
1✔
515
        for (Integer element : reverse(array)) {
1✔
516
            accum = func.apply(accum, element);
1✔
517
        }
1✔
518
        return accum;
1✔
519
    }
520

521
    public static <T, E> E reduceRight(
522
            final T[] array, final BiFunction<E, T, E> func, final E zeroElem) {
523
        return reduce(reverse(array), func, zeroElem);
1✔
524
    }
525

526
    public static <T, E> E foldr(
527
            final Iterable<T> iterable, final BiFunction<E, T, E> func, final E zeroElem) {
528
        return reduceRight(iterable, func, zeroElem);
1✔
529
    }
530

531
    /*
532
     * Documented, #find
533
     */
534
    public static <E> Optional<E> find(final Iterable<E> iterable, final Predicate<E> pred) {
535
        for (E element : iterable) {
1✔
536
            if (pred.test(element)) {
1✔
537
                return Optional.of(element);
1✔
538
            }
539
        }
1✔
540
        return Optional.empty();
1✔
541
    }
542

543
    public static <E> Optional<E> detect(final Iterable<E> iterable, final Predicate<E> pred) {
544
        return find(iterable, pred);
1✔
545
    }
546

547
    public static <E> Optional<E> findLast(final Iterable<E> iterable, final Predicate<E> pred) {
548
        return find(reverse(iterable), pred);
1✔
549
    }
550

551
    /*
552
     * Documented, #filter
553
     */
554
    public static <E> List<E> filter(final Iterable<E> iterable, final Predicate<E> pred) {
555
        final List<E> filtered = newArrayList();
1✔
556
        for (E element : iterable) {
1✔
557
            if (pred.test(element)) {
1✔
558
                filtered.add(element);
1✔
559
            }
560
        }
1✔
561
        return filtered;
1✔
562
    }
563

564
    public static <E> List<E> filter(final List<E> list, final Predicate<E> pred) {
565
        final List<E> filtered = newArrayList();
1✔
566
        for (E element : list) {
1✔
567
            if (pred.test(element)) {
1✔
568
                filtered.add(element);
1✔
569
            }
570
        }
1✔
571
        return filtered;
1✔
572
    }
573

574
    public List<T> filter(final Predicate<T> pred) {
575
        final List<T> filtered = newArrayList();
1✔
576
        for (final T element : value()) {
1✔
577
            if (pred.test(element)) {
1✔
578
                filtered.add(element);
1✔
579
            }
580
        }
1✔
581
        return filtered;
1✔
582
    }
583

584
    public static <E> List<E> filterIndexed(final List<E> list, final PredicateIndexed<E> pred) {
585
        final List<E> filtered = newArrayList();
1✔
586
        int index = 0;
1✔
587
        for (E element : list) {
1✔
588
            if (pred.test(index, element)) {
1✔
589
                filtered.add(element);
1✔
590
            }
591
            index += 1;
1✔
592
        }
1✔
593
        return filtered;
1✔
594
    }
595

596
    public static <E> Set<E> filter(final Set<E> set, final Predicate<E> pred) {
597
        final Set<E> filtered = newLinkedHashSet();
1✔
598
        for (E element : set) {
1✔
599
            if (pred.test(element)) {
1✔
600
                filtered.add(element);
1✔
601
            }
602
        }
1✔
603
        return filtered;
1✔
604
    }
605

606
    public static <E> List<E> select(final List<E> list, final Predicate<E> pred) {
607
        return filter(list, pred);
1✔
608
    }
609

610
    public static <E> Set<E> select(final Set<E> set, final Predicate<E> pred) {
611
        return filter(set, pred);
1✔
612
    }
613

614
    /*
615
     * Documented, #reject
616
     */
617
    public static <E> List<E> reject(final List<E> list, final Predicate<E> pred) {
618
        return filter(list, input -> !pred.test(input));
1✔
619
    }
620

621
    public List<T> reject(final Predicate<T> pred) {
622
        return filter(input -> !pred.test(input));
1✔
623
    }
624

625
    public static <E> List<E> rejectIndexed(final List<E> list, final PredicateIndexed<E> pred) {
626
        return filterIndexed(list, (index, input) -> !pred.test(index, input));
1✔
627
    }
628

629
    public static <E> Set<E> reject(final Set<E> set, final Predicate<E> pred) {
630
        return filter(set, input -> !pred.test(input));
1✔
631
    }
632

633
    public static <E> List<E> filterFalse(final List<E> list, final Predicate<E> pred) {
634
        return reject(list, pred);
1✔
635
    }
636

637
    public List<T> filterFalse(final Predicate<T> pred) {
638
        return reject(pred);
1✔
639
    }
640

641
    public static <E> Set<E> filterFalse(final Set<E> set, final Predicate<E> pred) {
642
        return reject(set, pred);
1✔
643
    }
644

645
    public static <E> boolean every(final Iterable<E> iterable, final Predicate<E> pred) {
646
        for (E item : iterable) {
1✔
647
            if (!pred.test(item)) {
1✔
648
                return false;
1✔
649
            }
650
        }
1✔
651
        return true;
1✔
652
    }
653

654
    public boolean every(final Predicate<T> pred) {
655
        return every(iterable, pred);
1✔
656
    }
657

658
    /*
659
     * Documented, #all
660
     */
661
    public static <E> boolean all(final Iterable<E> iterable, final Predicate<E> pred) {
662
        return every(iterable, pred);
1✔
663
    }
664

665
    public boolean all(final Predicate<T> pred) {
666
        return every(iterable, pred);
1✔
667
    }
668

669
    public static <E> boolean some(final Iterable<E> iterable, final Predicate<E> pred) {
670
        return find(iterable, pred).isPresent();
1✔
671
    }
672

673
    public boolean some(final Predicate<T> pred) {
674
        return some(iterable, pred);
1✔
675
    }
676

677
    /*
678
     * Documented, #any
679
     */
680
    public static <E> boolean any(final Iterable<E> iterable, final Predicate<E> pred) {
681
        return some(iterable, pred);
1✔
682
    }
683

684
    public boolean any(final Predicate<T> pred) {
685
        return some(iterable, pred);
1✔
686
    }
687

688
    public static <E> int count(final Iterable<E> iterable, final Predicate<E> pred) {
689
        int result = 0;
1✔
690
        for (E item : iterable) {
1✔
691
            if (pred.test(item)) {
1✔
692
                result += 1;
1✔
693
            }
694
        }
1✔
695
        return result;
1✔
696
    }
697

698
    public int count(final Predicate<T> pred) {
699
        return count(iterable, pred);
1✔
700
    }
701

702
    public static <E> boolean contains(final Iterable<E> iterable, final E elem) {
703
        return some(iterable, e -> Objects.equals(elem, e));
1✔
704
    }
705

706
    public boolean contains(final T elem) {
707
        return contains(iterable, elem);
1✔
708
    }
709

710
    public static <E> boolean containsWith(final Iterable<E> iterable, final E elem) {
711
        return some(
1✔
712
                iterable,
713
                e -> elem == null ? e == null : String.valueOf(e).contains(String.valueOf(elem)));
1✔
714
    }
715

716
    public boolean containsWith(final T elem) {
717
        return containsWith(iterable, elem);
1✔
718
    }
719

720
    public static <E> boolean contains(
721
            final Iterable<E> iterable, final E elem, final int fromIndex) {
722
        final List<E> list = newArrayList(iterable);
1✔
723
        return contains(list.subList(fromIndex, list.size()), elem);
1✔
724
    }
725

726
    public boolean containsAtLeast(final T value, final int count) {
727
        return Underscore.containsAtLeast(this.iterable, value, count);
1✔
728
    }
729

730
    public boolean containsAtMost(final T value, final int count) {
731
        return Underscore.containsAtMost(this.iterable, value, count);
1✔
732
    }
733

734
    public static <E> boolean containsAtLeast(
735
            final Iterable<E> iterable, final E value, final int count) {
736
        int foundItems = 0;
1✔
737
        for (E element : iterable) {
1✔
738
            if (Objects.equals(element, value)) {
1✔
739
                foundItems += 1;
1✔
740
            }
741
            if (foundItems >= count) {
1✔
742
                break;
1✔
743
            }
744
        }
1✔
745
        return foundItems >= count;
1✔
746
    }
747

748
    public static <E> boolean containsAtMost(
749
            final Iterable<E> iterable, final E value, final int count) {
750
        int foundItems = size(iterable);
1✔
751
        for (E element : iterable) {
1✔
752
            if (!(Objects.equals(element, value))) {
1✔
753
                foundItems -= 1;
1✔
754
            }
755
            if (foundItems <= count) {
1✔
756
                break;
1✔
757
            }
758
        }
1✔
759
        return foundItems <= count;
1✔
760
    }
761

762
    /*
763
     * Documented, #include
764
     */
765
    public static <E> boolean include(final Iterable<E> iterable, final E elem) {
766
        return contains(iterable, elem);
1✔
767
    }
768

769
    /*
770
     * Documented, #invoke
771
     */
772
    @SuppressWarnings("unchecked")
773
    public static <E> List<E> invoke(
774
            final Iterable<E> iterable, final String methodName, final List<Object> args) {
775
        final List<E> result = newArrayList();
1✔
776
        final List<Class<?>> argTypes = map(args, Object::getClass);
1✔
777
        try {
778
            final Method method =
1✔
779
                    iterable.iterator()
1✔
780
                            .next()
1✔
781
                            .getClass()
1✔
782
                            .getMethod(methodName, argTypes.toArray(new Class[0]));
1✔
783
            for (E arg : iterable) {
1✔
784
                doInvoke(args, result, method, arg);
1✔
785
            }
1✔
786
        } catch (NoSuchMethodException e) {
1✔
787
            throw new IllegalArgumentException(e);
1✔
788
        }
1✔
789
        return result;
1✔
790
    }
791

792
    @SuppressWarnings("unchecked")
793
    private static <E> void doInvoke(List<Object> args, List<E> result, Method method, E arg) {
794
        try {
795
            result.add((E) method.invoke(arg, args.toArray(new Object[0])));
1✔
796
        } catch (Exception e) {
1✔
797
            throw new IllegalArgumentException(e);
1✔
798
        }
1✔
799
    }
1✔
800

801
    public List<T> invoke(final String methodName, final List<Object> args) {
802
        return invoke(iterable, methodName, args);
1✔
803
    }
804

805
    public static <E> List<E> invoke(final Iterable<E> iterable, final String methodName) {
806
        return invoke(iterable, methodName, Collections.emptyList());
1✔
807
    }
808

809
    public List<T> invoke(final String methodName) {
810
        return invoke(iterable, methodName);
1✔
811
    }
812

813
    /*
814
     * Documented, #pluck
815
     */
816
    public static <E> List<Object> pluck(final List<E> list, final String propertyName) {
817
        if (list.isEmpty()) {
1✔
818
            return Collections.emptyList();
1✔
819
        }
820
        return map(
1✔
821
                list,
822
                elem -> {
823
                    try {
824
                        return elem.getClass().getField(propertyName).get(elem);
1✔
825
                    } catch (Exception e) {
1✔
826
                        try {
827
                            return elem.getClass().getMethod(propertyName).invoke(elem);
1✔
828
                        } catch (Exception ex) {
1✔
829
                            throw new IllegalArgumentException(ex);
1✔
830
                        }
831
                    }
832
                });
833
    }
834

835
    public List<Object> pluck(final String propertyName) {
836
        return pluck(newArrayList(iterable), propertyName);
1✔
837
    }
838

839
    public static <E> Set<Object> pluck(final Set<E> set, final String propertyName) {
840
        if (set.isEmpty()) {
1✔
841
            return Collections.emptySet();
1✔
842
        }
843
        return map(
1✔
844
                set,
845
                elem -> {
846
                    try {
847
                        return elem.getClass().getField(propertyName).get(elem);
1✔
848
                    } catch (Exception e) {
1✔
849
                        try {
850
                            return elem.getClass().getMethod(propertyName).invoke(elem);
1✔
851
                        } catch (Exception ex) {
1✔
852
                            throw new IllegalArgumentException(ex);
1✔
853
                        }
854
                    }
855
                });
856
    }
857

858
    /*
859
     * Documented, #where
860
     */
861
    public static <T, E> List<E> where(
862
            final List<E> list, final List<Map.Entry<String, T>> properties) {
863
        return filter(list, new WherePredicate<>(properties));
1✔
864
    }
865

866
    public <E> List<T> where(final List<Map.Entry<String, E>> properties) {
867
        return where(newArrayList(iterable), properties);
1✔
868
    }
869

870
    public static <T, E> Set<E> where(
871
            final Set<E> set, final List<Map.Entry<String, T>> properties) {
872
        return filter(set, new WherePredicate<>(properties));
1✔
873
    }
874

875
    /*
876
     * Documented, #findWhere
877
     */
878
    public static <T, E> Optional<E> findWhere(
879
            final Iterable<E> iterable, final List<Map.Entry<String, T>> properties) {
880
        return find(iterable, new WherePredicate<>(properties));
1✔
881
    }
882

883
    public <E> Optional<T> findWhere(final List<Map.Entry<String, E>> properties) {
884
        return findWhere(iterable, properties);
1✔
885
    }
886

887
    /*
888
     * Documented, #max
889
     */
890
    public static <E extends Comparable<? super E>> E max(final Collection<E> collection) {
891
        return Collections.max(collection);
1✔
892
    }
893

894
    @SuppressWarnings("unchecked")
895
    public T max() {
896
        return (T) max((Collection) iterable);
1✔
897
    }
898

899
    @SuppressWarnings("unchecked")
900
    public static <E, F extends Comparable> E max(
901
            final Collection<E> collection, final Function<E, F> func) {
902
        return Collections.max(collection, (o1, o2) -> func.apply(o1).compareTo(func.apply(o2)));
1✔
903
    }
904

905
    @SuppressWarnings("unchecked")
906
    public <F extends Comparable<? super F>> T max(final Function<T, F> func) {
907
        return (T) max((Collection) iterable, func);
1✔
908
    }
909

910
    /*
911
     * Documented, #min
912
     */
913
    public static <E extends Comparable<? super E>> E min(final Collection<E> collection) {
914
        return Collections.min(collection);
1✔
915
    }
916

917
    @SuppressWarnings("unchecked")
918
    public T min() {
919
        return (T) min((Collection) iterable);
1✔
920
    }
921

922
    @SuppressWarnings("unchecked")
923
    public static <E, F extends Comparable> E min(
924
            final Collection<E> collection, final Function<E, F> func) {
925
        return Collections.min(collection, (o1, o2) -> func.apply(o1).compareTo(func.apply(o2)));
1✔
926
    }
927

928
    @SuppressWarnings("unchecked")
929
    public <F extends Comparable<? super F>> T min(final Function<T, F> func) {
930
        return (T) min((Collection) iterable, func);
1✔
931
    }
932

933
    /*
934
     * Documented, #shuffle
935
     */
936
    public static <E> List<E> shuffle(final Iterable<E> iterable) {
937
        final List<E> shuffled = newArrayList(iterable);
1✔
938
        Collections.shuffle(shuffled);
1✔
939
        return shuffled;
1✔
940
    }
941

942
    public List<T> shuffle() {
943
        return shuffle(iterable);
1✔
944
    }
945

946
    /*
947
     * Documented, #sample
948
     */
949
    public static <E> E sample(final Iterable<E> iterable) {
950
        return newArrayList(iterable).get(new java.security.SecureRandom().nextInt(size(iterable)));
1✔
951
    }
952

953
    public T sample() {
954
        return sample(iterable);
1✔
955
    }
956

957
    public static <E> Set<E> sample(final List<E> list, final int howMany) {
958
        final int size = Math.min(howMany, list.size());
1✔
959
        final Set<E> samples = newLinkedHashSetWithExpectedSize(size);
1✔
960
        while (samples.size() < size) {
1✔
961
            E sample = sample(list);
1✔
962
            samples.add(sample);
1✔
963
        }
1✔
964
        return samples;
1✔
965
    }
966

967
    public static <T extends Comparable<? super T>> List<T> sortWith(
968
            final Iterable<T> iterable, final Comparator<T> comparator) {
969
        final List<T> sortedList = newArrayList(iterable);
1✔
970
        sortedList.sort(comparator);
1✔
971
        return sortedList;
1✔
972
    }
973

974
    @SuppressWarnings("unchecked")
975
    public <E extends Comparable<? super E>> List<E> sortWith(final Comparator<E> comparator) {
976
        return sortWith((Iterable<E>) iterable, comparator);
1✔
977
    }
978

979
    /*
980
     * Documented, #sortBy
981
     */
982
    public static <E, T extends Comparable<? super T>> List<E> sortBy(
983
            final Iterable<E> iterable, final Function<E, T> func) {
984
        final List<E> sortedList = newArrayList(iterable);
1✔
985
        sortedList.sort(Comparator.comparing(func));
1✔
986
        return sortedList;
1✔
987
    }
988

989
    @SuppressWarnings("unchecked")
990
    public <E, V extends Comparable<? super V>> List<E> sortBy(final Function<E, V> func) {
991
        return sortBy((Iterable<E>) iterable, func);
1✔
992
    }
993

994
    public static <K, V extends Comparable<? super V>> List<Map<K, V>> sortBy(
995
            final Iterable<Map<K, V>> iterable, final K key) {
996
        final List<Map<K, V>> sortedList = newArrayList(iterable);
1✔
997
        sortedList.sort(Comparator.comparing(o -> o.get(key)));
1✔
998
        return sortedList;
1✔
999
    }
1000

1001
    /*
1002
     * Documented, #groupBy
1003
     */
1004
    public static <K, E> Map<K, List<E>> groupBy(
1005
            final Iterable<E> iterable, final Function<E, K> func) {
1006
        final Map<K, List<E>> retVal = newLinkedHashMap();
1✔
1007
        for (E e : iterable) {
1✔
1008
            final K key = func.apply(e);
1✔
1009
            List<E> val;
1010
            if (retVal.containsKey(key)) {
1✔
1011
                val = retVal.get(key);
1✔
1012
            } else {
1013
                val = newArrayList();
1✔
1014
            }
1015
            val.add(e);
1✔
1016
            retVal.put(key, val);
1✔
1017
        }
1✔
1018
        return retVal;
1✔
1019
    }
1020

1021
    @SuppressWarnings("unchecked")
1022
    public <K, E> Map<K, List<E>> groupBy(final Function<E, K> func) {
1023
        return groupBy((Iterable<E>) iterable, func);
1✔
1024
    }
1025

1026
    public static <K, E> Map<K, Optional<E>> groupBy(
1027
            final Iterable<E> iterable,
1028
            final Function<E, K> func,
1029
            final BinaryOperator<E> binaryOperator) {
1030
        final Map<K, Optional<E>> retVal = newLinkedHashMap();
1✔
1031
        for (Map.Entry<K, List<E>> entry : groupBy(iterable, func).entrySet()) {
1✔
1032
            retVal.put(entry.getKey(), reduce(entry.getValue(), binaryOperator));
1✔
1033
        }
1✔
1034
        return retVal;
1✔
1035
    }
1036

1037
    @SuppressWarnings("unchecked")
1038
    public <K, E> Map<K, Optional<E>> groupBy(
1039
            final Function<E, K> func, final BinaryOperator<E> binaryOperator) {
1040
        return groupBy((Iterable<E>) iterable, func, binaryOperator);
1✔
1041
    }
1042

1043
    @SuppressWarnings("unchecked")
1044
    public static <K, E> Map<K, List<E>> indexBy(
1045
            final Iterable<E> iterable, final String property) {
1046
        return groupBy(
1✔
1047
                iterable,
1048
                elem -> {
1049
                    try {
1050
                        return (K) elem.getClass().getField(property).get(elem);
1✔
1051
                    } catch (Exception e) {
1✔
1052
                        return null;
1✔
1053
                    }
1054
                });
1055
    }
1056

1057
    @SuppressWarnings("unchecked")
1058
    public <K, E> Map<K, List<E>> indexBy(final String property) {
1059
        return indexBy((Iterable<E>) iterable, property);
1✔
1060
    }
1061

1062
    /*
1063
     * Documented, #countBy
1064
     */
1065
    public static <K, E> Map<K, Integer> countBy(final Iterable<E> iterable, Function<E, K> func) {
1066
        final Map<K, Integer> retVal = newLinkedHashMap();
1✔
1067
        for (E e : iterable) {
1✔
1068
            final K key = func.apply(e);
1✔
1069
            if (retVal.containsKey(key)) {
1✔
1070
                retVal.put(key, 1 + retVal.get(key));
1✔
1071
            } else {
1072
                retVal.put(key, 1);
1✔
1073
            }
1074
        }
1✔
1075
        return retVal;
1✔
1076
    }
1077

1078
    public static <K> Map<K, Integer> countBy(final Iterable<K> iterable) {
1079
        final Map<K, Integer> retVal = newLinkedHashMap();
1✔
1080
        for (K key : iterable) {
1✔
1081
            if (retVal.containsKey(key)) {
1✔
1082
                retVal.put(key, 1 + retVal.get(key));
1✔
1083
            } else {
1084
                retVal.put(key, 1);
1✔
1085
            }
1086
        }
1✔
1087
        return retVal;
1✔
1088
    }
1089

1090
    @SuppressWarnings("unchecked")
1091
    public <K, E> Map<K, Integer> countBy(Function<E, K> func) {
1092
        return countBy((Iterable<E>) iterable, func);
1✔
1093
    }
1094

1095
    @SuppressWarnings("unchecked")
1096
    public <K> Map<K, Integer> countBy() {
1097
        return countBy((Iterable<K>) iterable);
1✔
1098
    }
1099

1100
    /*
1101
     * Documented, #toArray
1102
     */
1103
    @SuppressWarnings("unchecked")
1104
    public static <E> E[] toArray(final Iterable<E> iterable) {
1105
        return (E[]) newArrayList(iterable).toArray();
1✔
1106
    }
1107

1108
    @SuppressWarnings("unchecked")
1109
    public <E> E[] toArray() {
1110
        return toArray((Iterable<E>) iterable);
1✔
1111
    }
1112

1113
    /*
1114
     * Documented, #toMap
1115
     */
1116
    public static <K, V> Map<K, V> toMap(final Iterable<Map.Entry<K, V>> iterable) {
1117
        final Map<K, V> result = newLinkedHashMap();
1✔
1118
        for (Map.Entry<K, V> entry : iterable) {
1✔
1119
            result.put(entry.getKey(), entry.getValue());
1✔
1120
        }
1✔
1121
        return result;
1✔
1122
    }
1123

1124
    @SuppressWarnings("unchecked")
1125
    public <K, V> Map<K, V> toMap() {
1126
        return toMap((Iterable<Map.Entry<K, V>>) iterable);
1✔
1127
    }
1128

1129
    public static <K, V> Map<K, V> toMap(final List<Map.Entry<K, V>> tuples) {
1130
        final Map<K, V> result = newLinkedHashMap();
1✔
1131
        for (final Map.Entry<K, V> entry : tuples) {
1✔
1132
            result.put(entry.getKey(), entry.getValue());
1✔
1133
        }
1✔
1134
        return result;
1✔
1135
    }
1136

1137
    public Map<T, Integer> toCardinalityMap() {
1138
        return toCardinalityMap(iterable);
1✔
1139
    }
1140

1141
    public static <K> Map<K, Integer> toCardinalityMap(final Iterable<K> iterable) {
1142
        Iterator<K> iterator = iterable.iterator();
1✔
1143
        Map<K, Integer> result = newLinkedHashMap();
1✔
1144

1145
        while (iterator.hasNext()) {
1✔
1146
            K item = iterator.next();
1✔
1147

1148
            if (result.containsKey(item)) {
1✔
1149
                result.put(item, result.get(item) + 1);
1✔
1150
            } else {
1151
                result.put(item, 1);
1✔
1152
            }
1153
        }
1✔
1154
        return result;
1✔
1155
    }
1156

1157
    /*
1158
     * Documented, #size
1159
     */
1160
    public static int size(final Iterable<?> iterable) {
1161
        if (iterable instanceof Collection) {
1✔
1162
            return ((Collection) iterable).size();
1✔
1163
        }
1164
        int size;
1165
        final Iterator<?> iterator = iterable.iterator();
1✔
1166
        for (size = 0; iterator.hasNext(); size += 1) {
1✔
1167
            iterator.next();
1✔
1168
        }
1169
        return size;
1✔
1170
    }
1171

1172
    public int size() {
1173
        return size(iterable);
1✔
1174
    }
1175

1176
    @SuppressWarnings("unchecked")
1177
    public static <E> int size(final E... array) {
1178
        return array.length;
1✔
1179
    }
1180

1181
    public static <E> List<List<E>> partition(final Iterable<E> iterable, final Predicate<E> pred) {
1182
        final List<E> retVal1 = newArrayList();
1✔
1183
        final List<E> retVal2 = newArrayList();
1✔
1184
        for (final E e : iterable) {
1✔
1185
            if (pred.test(e)) {
1✔
1186
                retVal1.add(e);
1✔
1187
            } else {
1188
                retVal2.add(e);
1✔
1189
            }
1190
        }
1✔
1191
        return Arrays.asList(retVal1, retVal2);
1✔
1192
    }
1193

1194
    @SuppressWarnings("unchecked")
1195
    public static <E> List<E>[] partition(final E[] iterable, final Predicate<E> pred) {
1196
        return partition(Arrays.asList(iterable), pred).toArray(new ArrayList[0]);
1✔
1197
    }
1198

1199
    public T singleOrNull() {
1200
        return singleOrNull(iterable);
1✔
1201
    }
1202

1203
    public T singleOrNull(Predicate<T> pred) {
1204
        return singleOrNull(iterable, pred);
1✔
1205
    }
1206

1207
    public static <E> E singleOrNull(final Iterable<E> iterable) {
1208
        Iterator<E> iterator = iterable.iterator();
1✔
1209
        if (!iterator.hasNext()) {
1✔
1210
            return null;
1✔
1211
        }
1212
        E result = iterator.next();
1✔
1213

1214
        if (iterator.hasNext()) {
1✔
1215
            result = null;
1✔
1216
        }
1217
        return result;
1✔
1218
    }
1219

1220
    public static <E> E singleOrNull(final Iterable<E> iterable, Predicate<E> pred) {
1221
        return singleOrNull(filter(iterable, pred));
1✔
1222
    }
1223

1224
    /*
1225
     * Documented, #first
1226
     */
1227
    public static <E> E first(final Iterable<E> iterable) {
1228
        return iterable.iterator().next();
1✔
1229
    }
1230

1231
    @SuppressWarnings("unchecked")
1232
    public static <E> E first(final E... array) {
1233
        return array[0];
1✔
1234
    }
1235

1236
    public static <E> List<E> first(final List<E> list, final int n) {
1237
        return list.subList(0, Math.min(n < 0 ? 0 : n, list.size()));
1✔
1238
    }
1239

1240
    public T first() {
1241
        return first(iterable);
1✔
1242
    }
1243

1244
    public List<T> first(final int n) {
1245
        return first(newArrayList(iterable), n);
1✔
1246
    }
1247

1248
    public static <E> E first(final Iterable<E> iterable, final Predicate<E> pred) {
1249
        return filter(newArrayList(iterable), pred).iterator().next();
1✔
1250
    }
1251

1252
    public static <E> List<E> first(
1253
            final Iterable<E> iterable, final Predicate<E> pred, final int n) {
1254
        List<E> list = filter(newArrayList(iterable), pred);
1✔
1255
        return list.subList(0, Math.min(n < 0 ? 0 : n, list.size()));
1✔
1256
    }
1257

1258
    public T first(final Predicate<T> pred) {
1259
        return first(newArrayList(iterable), pred);
1✔
1260
    }
1261

1262
    public List<T> first(final Predicate<T> pred, final int n) {
1263
        return first(newArrayList(iterable), pred, n);
1✔
1264
    }
1265

1266
    public static <E> E firstOrNull(final Iterable<E> iterable) {
1267
        final Iterator<E> iterator = iterable.iterator();
1✔
1268
        return iterator.hasNext() ? iterator.next() : null;
1✔
1269
    }
1270

1271
    public T firstOrNull() {
1272
        return firstOrNull(iterable);
1✔
1273
    }
1274

1275
    public static <E> E firstOrNull(final Iterable<E> iterable, final Predicate<E> pred) {
1276
        final Iterator<E> iterator = filter(newArrayList(iterable), pred).iterator();
1✔
1277
        return iterator.hasNext() ? iterator.next() : null;
1✔
1278
    }
1279

1280
    public T firstOrNull(final Predicate<T> pred) {
1281
        return firstOrNull(iterable, pred);
1✔
1282
    }
1283

1284
    public static <E> E head(final Iterable<E> iterable) {
1285
        return first(iterable);
1✔
1286
    }
1287

1288
    @SuppressWarnings("unchecked")
1289
    public static <E> E head(final E... array) {
1290
        return first(array);
1✔
1291
    }
1292

1293
    public static <E> List<E> head(final List<E> list, final int n) {
1294
        return first(list, n);
1✔
1295
    }
1296

1297
    public T head() {
1298
        return first();
1✔
1299
    }
1300

1301
    public List<T> head(final int n) {
1302
        return first(n);
1✔
1303
    }
1304

1305
    /*
1306
     * Documented, #initial
1307
     */
1308
    public static <E> List<E> initial(final List<E> list) {
1309
        return initial(list, 1);
1✔
1310
    }
1311

1312
    public static <E> List<E> initial(final List<E> list, final int n) {
1313
        return list.subList(0, Math.max(0, list.size() - n));
1✔
1314
    }
1315

1316
    @SuppressWarnings("unchecked")
1317
    public static <E> E[] initial(final E... array) {
1318
        return initial(array, 1);
1✔
1319
    }
1320

1321
    public static <E> E[] initial(final E[] array, final int n) {
1322
        return Arrays.copyOf(array, array.length - n);
1✔
1323
    }
1324

1325
    public List<T> initial() {
1326
        return initial((List<T>) iterable, 1);
1✔
1327
    }
1328

1329
    public List<T> initial(final int n) {
1330
        return initial((List<T>) iterable, n);
1✔
1331
    }
1332

1333
    @SuppressWarnings("unchecked")
1334
    public static <E> E last(final E... array) {
1335
        return array[array.length - 1];
1✔
1336
    }
1337

1338
    /*
1339
     * Documented, #last
1340
     */
1341
    public static <E> E last(final List<E> list) {
1342
        return list.get(list.size() - 1);
1✔
1343
    }
1344

1345
    public static <E> List<E> last(final List<E> list, final int n) {
1346
        return list.subList(Math.max(0, list.size() - n), list.size());
1✔
1347
    }
1348

1349
    public T last() {
1350
        return last((List<T>) iterable);
1✔
1351
    }
1352

1353
    public List<T> last(final int n) {
1354
        return last((List<T>) iterable, n);
1✔
1355
    }
1356

1357
    public static <E> E last(final List<E> list, final Predicate<E> pred) {
1358
        final List<E> filteredList = filter(list, pred);
1✔
1359
        return filteredList.get(filteredList.size() - 1);
1✔
1360
    }
1361

1362
    public T last(final Predicate<T> pred) {
1363
        return last((List<T>) iterable, pred);
1✔
1364
    }
1365

1366
    public static <E> E lastOrNull(final List<E> list) {
1367
        return list.isEmpty() ? null : list.get(list.size() - 1);
1✔
1368
    }
1369

1370
    public T lastOrNull() {
1371
        return lastOrNull((List<T>) iterable);
1✔
1372
    }
1373

1374
    public static <E> E lastOrNull(final List<E> list, final Predicate<E> pred) {
1375
        final List<E> filteredList = filter(list, pred);
1✔
1376
        return filteredList.isEmpty() ? null : filteredList.get(filteredList.size() - 1);
1✔
1377
    }
1378

1379
    public T lastOrNull(final Predicate<T> pred) {
1380
        return lastOrNull((List<T>) iterable, pred);
1✔
1381
    }
1382

1383
    /*
1384
     * Documented, #rest
1385
     */
1386
    public static <E> List<E> rest(final List<E> list) {
1387
        return rest(list, 1);
1✔
1388
    }
1389

1390
    public static <E> List<E> rest(final List<E> list, int n) {
1391
        return list.subList(Math.min(n, list.size()), list.size());
1✔
1392
    }
1393

1394
    @SuppressWarnings("unchecked")
1395
    public static <E> E[] rest(final E... array) {
1396
        return rest(array, 1);
1✔
1397
    }
1398

1399
    @SuppressWarnings("unchecked")
1400
    public static <E> E[] rest(final E[] array, final int n) {
1401
        return (E[]) rest(Arrays.asList(array), n).toArray();
1✔
1402
    }
1403

1404
    public List<T> rest() {
1405
        return rest((List<T>) iterable);
1✔
1406
    }
1407

1408
    public List<T> rest(int n) {
1409
        return rest((List<T>) iterable, n);
1✔
1410
    }
1411

1412
    public static <E> List<E> tail(final List<E> list) {
1413
        return rest(list);
1✔
1414
    }
1415

1416
    public static <E> List<E> tail(final List<E> list, final int n) {
1417
        return rest(list, n);
1✔
1418
    }
1419

1420
    @SuppressWarnings("unchecked")
1421
    public static <E> E[] tail(final E... array) {
1422
        return rest(array);
1✔
1423
    }
1424

1425
    public static <E> E[] tail(final E[] array, final int n) {
1426
        return rest(array, n);
1✔
1427
    }
1428

1429
    public List<T> tail() {
1430
        return rest();
1✔
1431
    }
1432

1433
    public List<T> tail(final int n) {
1434
        return rest(n);
1✔
1435
    }
1436

1437
    public static <E> List<E> drop(final List<E> list) {
1438
        return rest(list);
1✔
1439
    }
1440

1441
    public static <E> List<E> drop(final List<E> list, final int n) {
1442
        return rest(list, n);
1✔
1443
    }
1444

1445
    @SuppressWarnings("unchecked")
1446
    public static <E> E[] drop(final E... array) {
1447
        return rest(array);
1✔
1448
    }
1449

1450
    public static <E> E[] drop(final E[] array, final int n) {
1451
        return rest(array, n);
1✔
1452
    }
1453

1454
    /*
1455
     * Documented, #compact
1456
     */
1457
    public static <E> List<E> compact(final List<E> list) {
1458
        return filter(
1✔
1459
                list,
1460
                arg ->
1461
                        !String.valueOf(arg).equals("null")
1✔
1462
                                && !String.valueOf(arg).equals("0")
1✔
1463
                                && !String.valueOf(arg).equals("false")
1✔
1464
                                && !String.valueOf(arg).equals(""));
1✔
1465
    }
1466

1467
    @SuppressWarnings("unchecked")
1468
    public static <E> E[] compact(final E... array) {
1469
        return (E[]) compact(Arrays.asList(array)).toArray();
1✔
1470
    }
1471

1472
    public static <E> List<E> compact(final List<E> list, final E falsyValue) {
1473
        return filter(list, arg -> !(Objects.equals(arg, falsyValue)));
1✔
1474
    }
1475

1476
    @SuppressWarnings("unchecked")
1477
    public static <E> E[] compact(final E[] array, final E falsyValue) {
1478
        return (E[]) compact(Arrays.asList(array), falsyValue).toArray();
1✔
1479
    }
1480

1481
    public List<T> compact() {
1482
        return compact((List<T>) iterable);
1✔
1483
    }
1484

1485
    public List<T> compact(final T falsyValue) {
1486
        return compact((List<T>) iterable, falsyValue);
1✔
1487
    }
1488

1489
    /*
1490
     * Documented, #flatten
1491
     */
1492
    public static <E> List<E> flatten(final List<?> list) {
1493
        List<E> flattened = newArrayList();
1✔
1494
        flatten(list, flattened, -1);
1✔
1495
        return flattened;
1✔
1496
    }
1497

1498
    public static <E> List<E> flatten(final List<?> list, final boolean shallow) {
1499
        List<E> flattened = newArrayList();
1✔
1500
        flatten(list, flattened, shallow ? 1 : -1);
1✔
1501
        return flattened;
1✔
1502
    }
1503

1504
    @SuppressWarnings("unchecked")
1505
    private static <E> void flatten(
1506
            final List<?> fromTreeList, final List<E> toFlatList, final int shallowLevel) {
1507
        for (Object item : fromTreeList) {
1✔
1508
            if (item instanceof List<?> && shallowLevel != 0) {
1✔
1509
                flatten((List<?>) item, toFlatList, shallowLevel - 1);
1✔
1510
            } else {
1511
                toFlatList.add((E) item);
1✔
1512
            }
1513
        }
1✔
1514
    }
1✔
1515

1516
    public List<T> flatten() {
1517
        return flatten((List<T>) iterable);
1✔
1518
    }
1519

1520
    public List<T> flatten(final boolean shallow) {
1521
        return flatten((List<T>) iterable, shallow);
1✔
1522
    }
1523

1524
    /*
1525
     * Documented, #without
1526
     */
1527
    @SuppressWarnings("unchecked")
1528
    public static <E> List<E> without(final List<E> list, E... values) {
1529
        final List<E> valuesList = Arrays.asList(values);
1✔
1530
        return filter(list, elem -> !contains(valuesList, elem));
1✔
1531
    }
1532

1533
    @SuppressWarnings("unchecked")
1534
    public static <E> E[] without(final E[] array, final E... values) {
1535
        return (E[]) without(Arrays.asList(array), values).toArray();
1✔
1536
    }
1537

1538
    /*
1539
     * Documented, #uniq
1540
     */
1541
    public static <E> List<E> uniq(final List<E> list) {
1542
        return newArrayList(newLinkedHashSet(list));
1✔
1543
    }
1544

1545
    @SuppressWarnings("unchecked")
1546
    public static <E> E[] uniq(final E... array) {
1547
        return (E[]) uniq(Arrays.asList(array)).toArray();
1✔
1548
    }
1549

1550
    public static <K, E> Collection<E> uniq(final Iterable<E> iterable, final Function<E, K> func) {
1551
        final Map<K, E> retVal = newLinkedHashMap();
1✔
1552
        for (final E e : iterable) {
1✔
1553
            final K key = func.apply(e);
1✔
1554
            retVal.put(key, e);
1✔
1555
        }
1✔
1556
        return retVal.values();
1✔
1557
    }
1558

1559
    @SuppressWarnings("unchecked")
1560
    public static <K, E> E[] uniq(final E[] array, final Function<E, K> func) {
1561
        return (E[]) uniq(Arrays.asList(array), func).toArray();
1✔
1562
    }
1563

1564
    public static <E> List<E> distinct(final List<E> list) {
1565
        return uniq(list);
1✔
1566
    }
1567

1568
    @SuppressWarnings("unchecked")
1569
    public static <E> E[] distinct(final E... array) {
1570
        return uniq(array);
1✔
1571
    }
1572

1573
    public static <K, E> Collection<E> distinctBy(
1574
            final Iterable<E> iterable, final Function<E, K> func) {
1575
        return uniq(iterable, func);
1✔
1576
    }
1577

1578
    public static <K, E> E[] distinctBy(final E[] array, final Function<E, K> func) {
1579
        return uniq(array, func);
1✔
1580
    }
1581

1582
    /*
1583
     * Documented, #union
1584
     */
1585
    @SuppressWarnings("unchecked")
1586
    public static <E> List<E> union(final List<E> list, final List<E>... lists) {
1587
        final Set<E> union = newLinkedHashSet();
1✔
1588
        union.addAll(list);
1✔
1589
        for (List<E> localList : lists) {
1✔
1590
            union.addAll(localList);
1✔
1591
        }
1592
        return newArrayList(union);
1✔
1593
    }
1594

1595
    @SuppressWarnings("unchecked")
1596
    public List<T> unionWith(final List<T>... lists) {
1597
        return union(newArrayList(iterable), lists);
1✔
1598
    }
1599

1600
    @SuppressWarnings("unchecked")
1601
    public static <E> E[] union(final E[]... arrays) {
1602
        final Set<E> union = newLinkedHashSet();
1✔
1603
        for (E[] array : arrays) {
1✔
1604
            union.addAll(Arrays.asList(array));
1✔
1605
        }
1606
        return (E[]) newArrayList(union).toArray();
1✔
1607
    }
1608

1609
    /*
1610
     * Documented, #intersection
1611
     */
1612
    public static <E> List<E> intersection(final List<E> list1, final List<E> list2) {
1613
        final List<E> result = newArrayList();
1✔
1614
        for (final E item : list1) {
1✔
1615
            if (list2.contains(item)) {
1✔
1616
                result.add(item);
1✔
1617
            }
1618
        }
1✔
1619
        return result;
1✔
1620
    }
1621

1622
    @SuppressWarnings("unchecked")
1623
    public static <E> List<E> intersection(final List<E> list, final List<E>... lists) {
1624
        final Deque<List<E>> stack = new ArrayDeque<>();
1✔
1625
        stack.push(list);
1✔
1626
        for (List<E> es : lists) {
1✔
1627
            stack.push(intersection(stack.peek(), es));
1✔
1628
        }
1629
        return stack.peek();
1✔
1630
    }
1631

1632
    @SuppressWarnings("unchecked")
1633
    public List<T> intersectionWith(final List<T>... lists) {
1634
        return intersection(newArrayList(iterable), lists);
1✔
1635
    }
1636

1637
    @SuppressWarnings("unchecked")
1638
    public static <E> E[] intersection(final E[]... arrays) {
1639
        final Deque<List<E>> stack = new ArrayDeque<>();
1✔
1640
        stack.push(Arrays.asList(arrays[0]));
1✔
1641
        for (int index = 1; index < arrays.length; index += 1) {
1✔
1642
            stack.push(intersection(stack.peek(), Arrays.asList(arrays[index])));
1✔
1643
        }
1644
        return (E[]) stack.peek().toArray();
1✔
1645
    }
1646

1647
    /*
1648
     * Documented, #difference
1649
     */
1650
    public static <E> List<E> difference(final List<E> list1, final List<E> list2) {
1651
        final List<E> result = newArrayList();
1✔
1652
        for (final E item : list1) {
1✔
1653
            if (!list2.contains(item)) {
1✔
1654
                result.add(item);
1✔
1655
            }
1656
        }
1✔
1657
        return result;
1✔
1658
    }
1659

1660
    @SuppressWarnings("unchecked")
1661
    public static <E> List<E> difference(final List<E> list, final List<E>... lists) {
1662
        final Deque<List<E>> stack = new ArrayDeque<>();
1✔
1663
        stack.push(list);
1✔
1664
        for (List<E> es : lists) {
1✔
1665
            stack.push(difference(stack.peek(), es));
1✔
1666
        }
1667
        return stack.peek();
1✔
1668
    }
1669

1670
    @SuppressWarnings("unchecked")
1671
    public List<T> differenceWith(final List<T>... lists) {
1672
        return difference(newArrayList(iterable), lists);
1✔
1673
    }
1674

1675
    @SuppressWarnings("unchecked")
1676
    public static <E> E[] difference(final E[]... arrays) {
1677
        final Deque<List<E>> stack = new ArrayDeque<>();
1✔
1678
        stack.push(Arrays.asList(arrays[0]));
1✔
1679
        for (int index = 1; index < arrays.length; index += 1) {
1✔
1680
            stack.push(difference(stack.peek(), Arrays.asList(arrays[index])));
1✔
1681
        }
1682
        return (E[]) stack.peek().toArray();
1✔
1683
    }
1684

1685
    /*
1686
     * Documented, #zip
1687
     */
1688
    @SuppressWarnings("unchecked")
1689
    public static <T> List<List<T>> zip(final List<T>... lists) {
1690
        final List<List<T>> zipped = newArrayList();
1✔
1691
        each(
1✔
1692
                Arrays.asList(lists),
1✔
1693
                list -> {
1694
                    int index = 0;
1✔
1695
                    for (T elem : list) {
1✔
1696
                        final List<T> nTuple =
1697
                                index >= zipped.size()
1✔
1698
                                        ? Underscore.newArrayList()
1✔
1699
                                        : zipped.get(index);
1✔
1700
                        if (index >= zipped.size()) {
1✔
1701
                            zipped.add(nTuple);
1✔
1702
                        }
1703
                        index += 1;
1✔
1704
                        nTuple.add(elem);
1✔
1705
                    }
1✔
1706
                });
1✔
1707
        return zipped;
1✔
1708
    }
1709

1710
    @SuppressWarnings("unchecked")
1711
    public static <T> List<List<T>> unzip(final List<T>... lists) {
1712
        final List<List<T>> unzipped = newArrayList();
1✔
1713
        for (int index = 0; index < lists[0].size(); index += 1) {
1✔
1714
            final List<T> nTuple = newArrayList();
1✔
1715
            for (List<T> list : lists) {
1✔
1716
                nTuple.add(list.get(index));
1✔
1717
            }
1718
            unzipped.add(nTuple);
1✔
1719
        }
1720
        return unzipped;
1✔
1721
    }
1722

1723
    /*
1724
     * Documented, #object
1725
     */
1726
    public static <K, V> List<Map.Entry<K, V>> object(final List<K> keys, final List<V> values) {
1727
        return map(
1✔
1728
                keys,
1729
                new Function<>() {
1✔
1730
                    private int index;
1731

1732
                    @Override
1733
                    public Map.Entry<K, V> apply(K key) {
1734
                        return Map.entry(key, values.get(index++));
1✔
1735
                    }
1736
                });
1737
    }
1738

1739
    public static <E> int findIndex(final List<E> list, final Predicate<E> pred) {
1740
        for (int index = 0; index < list.size(); index++) {
1✔
1741
            if (pred.test(list.get(index))) {
1✔
1742
                return index;
1✔
1743
            }
1744
        }
1745
        return -1;
1✔
1746
    }
1747

1748
    public static <E> int findIndex(final E[] array, final Predicate<E> pred) {
1749
        return findIndex(Arrays.asList(array), pred);
1✔
1750
    }
1751

1752
    public static <E> int findLastIndex(final List<E> list, final Predicate<E> pred) {
1753
        for (int index = list.size() - 1; index >= 0; index--) {
1✔
1754
            if (pred.test(list.get(index))) {
1✔
1755
                return index;
1✔
1756
            }
1757
        }
1758
        return -1;
1✔
1759
    }
1760

1761
    public static <E> int findLastIndex(final E[] array, final Predicate<E> pred) {
1762
        return findLastIndex(Arrays.asList(array), pred);
1✔
1763
    }
1764

1765
    public static <E extends Comparable<E>> int binarySearch(
1766
            final Iterable<E> iterable, final E key) {
1767
        if (key == null) {
1✔
1768
            return first(iterable) == null ? 0 : -1;
1✔
1769
        }
1770
        int begin = 0;
1✔
1771
        int end = size(iterable) - 1;
1✔
1772
        int numberOfNullValues = 0;
1✔
1773
        List<E> list = new ArrayList<>();
1✔
1774
        for (E item : iterable) {
1✔
1775
            if (item == null) {
1✔
1776
                numberOfNullValues++;
1✔
1777
                end--;
1✔
1778
            } else {
1779
                list.add(item);
1✔
1780
            }
1781
        }
1✔
1782
        while (begin <= end) {
1✔
1783
            int middle = begin + (end - begin) / 2;
1✔
1784
            if (key.compareTo(list.get(middle)) < 0) {
1✔
1785
                end = middle - 1;
1✔
1786
            } else if (key.compareTo(list.get(middle)) > 0) {
1✔
1787
                begin = middle + 1;
1✔
1788
            } else {
1789
                return middle + numberOfNullValues;
1✔
1790
            }
1791
        }
1✔
1792
        return -(begin + numberOfNullValues + 1);
1✔
1793
    }
1794

1795
    public static <E extends Comparable<E>> int binarySearch(final E[] array, final E key) {
1796
        return binarySearch(Arrays.asList(array), key);
1✔
1797
    }
1798

1799
    /*
1800
     * Documented, #sortedIndex
1801
     */
1802
    public static <E extends Comparable<E>> int sortedIndex(final List<E> list, final E value) {
1803
        int index = 0;
1✔
1804
        for (E elem : list) {
1✔
1805
            if (elem.compareTo(value) >= 0) {
1✔
1806
                return index;
1✔
1807
            }
1808
            index += 1;
1✔
1809
        }
1✔
1810
        return -1;
1✔
1811
    }
1812

1813
    public static <E extends Comparable<E>> int sortedIndex(final E[] array, final E value) {
1814
        return sortedIndex(Arrays.asList(array), value);
1✔
1815
    }
1816

1817
    @SuppressWarnings("unchecked")
1818
    public static <E extends Comparable<E>> int sortedIndex(
1819
            final List<E> list, final E value, final String propertyName) {
1820
        try {
1821
            final Field property = value.getClass().getField(propertyName);
1✔
1822
            final Object valueProperty = property.get(value);
1✔
1823
            int index = 0;
1✔
1824
            for (E elem : list) {
1✔
1825
                if (((Comparable) property.get(elem)).compareTo(valueProperty) >= 0) {
1✔
1826
                    return index;
1✔
1827
                }
1828
                index += 1;
1✔
1829
            }
1✔
1830
            return -1;
1✔
1831
        } catch (Exception e) {
1✔
1832
            throw new IllegalArgumentException(e);
1✔
1833
        }
1834
    }
1835

1836
    public static <E extends Comparable<E>> int sortedIndex(
1837
            final E[] array, final E value, final String propertyName) {
1838
        return sortedIndex(Arrays.asList(array), value, propertyName);
1✔
1839
    }
1840

1841
    /*
1842
     * Documented, #indexOf
1843
     */
1844
    public static <E> int indexOf(final List<E> list, final E value) {
1845
        return list.indexOf(value);
1✔
1846
    }
1847

1848
    public static <E> int indexOf(final E[] array, final E value) {
1849
        return indexOf(Arrays.asList(array), value);
1✔
1850
    }
1851

1852
    /*
1853
     * Documented, #lastIndexOf
1854
     */
1855
    public static <E> int lastIndexOf(final List<E> list, final E value) {
1856
        return list.lastIndexOf(value);
1✔
1857
    }
1858

1859
    public static <E> int lastIndexOf(final E[] array, final E value) {
1860
        return lastIndexOf(Arrays.asList(array), value);
1✔
1861
    }
1862

1863
    /*
1864
     * Documented, #range
1865
     */
1866
    public static List<Integer> range(int stop) {
1867
        return range(0, stop, 1);
1✔
1868
    }
1869

1870
    public static List<Integer> range(int start, int stop) {
1871
        return range(start, stop, start < stop ? 1 : -1);
1✔
1872
    }
1873

1874
    public static List<Integer> range(int start, int stop, int step) {
1875
        List<Integer> list = Underscore.newArrayList();
1✔
1876
        if (step == 0) {
1✔
1877
            return list;
1✔
1878
        }
1879
        if (start < stop) {
1✔
1880
            for (int value = start; value < stop; value += step) {
1✔
1881
                list.add(value);
1✔
1882
            }
1883
        } else {
1884
            for (int value = start; value > stop; value += step) {
1✔
1885
                list.add(value);
1✔
1886
            }
1887
        }
1888
        return list;
1✔
1889
    }
1890

1891
    public static List<Character> range(char stop) {
1892
        return range('a', stop, 1);
1✔
1893
    }
1894

1895
    public static List<Character> range(char start, char stop) {
1896
        return range(start, stop, start < stop ? 1 : -1);
1✔
1897
    }
1898

1899
    public static List<Character> range(char start, char stop, int step) {
1900
        List<Character> list = Underscore.newArrayList();
1✔
1901
        if (step == 0) {
1✔
1902
            return list;
1✔
1903
        }
1904
        if (start < stop) {
1✔
1905
            for (char value = start; value < stop; value += step) {
1✔
1906
                list.add(value);
1✔
1907
            }
1908
        } else {
1909
            for (char value = start; value > stop; value += step) {
1✔
1910
                list.add(value);
1✔
1911
            }
1912
        }
1913
        return list;
1✔
1914
    }
1915

1916
    public static <T> List<List<T>> chunk(final Iterable<T> iterable, final int size) {
1917
        if (size <= 0) {
1✔
1918
            return newArrayList();
1✔
1919
        }
1920
        return chunk(iterable, size, size);
1✔
1921
    }
1922

1923
    public static <T> List<List<T>> chunk(
1924
            final Iterable<T> iterable, final int size, final int step) {
1925
        if (step <= 0 || size < 0) {
1✔
1926
            return newArrayList();
1✔
1927
        }
1928
        int index = 0;
1✔
1929
        int length = size(iterable);
1✔
1930
        final List<List<T>> result = new ArrayList<>(size == 0 ? size : (length / size) + 1);
1✔
1931
        while (index < length) {
1✔
1932
            result.add(newArrayList(iterable).subList(index, Math.min(length, index + size)));
1✔
1933
            index += step;
1✔
1934
        }
1935
        return result;
1✔
1936
    }
1937

1938
    public static <T> List<List<T>> chunkFill(
1939
            final Iterable<T> iterable, final int size, final T fillValue) {
1940
        if (size <= 0) {
1✔
1941
            return newArrayList();
1✔
1942
        }
1943
        return chunkFill(iterable, size, size, fillValue);
1✔
1944
    }
1945

1946
    public static <T> List<List<T>> chunkFill(
1947
            final Iterable<T> iterable, final int size, final int step, final T fillValue) {
1948
        if (step <= 0 || size < 0) {
1✔
1949
            return newArrayList();
1✔
1950
        }
1951
        final List<List<T>> result = chunk(iterable, size, step);
1✔
1952
        int difference = size - result.get(result.size() - 1).size();
1✔
1953
        for (int i = difference; 0 < i; i--) {
1✔
1954
            result.get(result.size() - 1).add(fillValue);
1✔
1955
        }
1956
        return result;
1✔
1957
    }
1958

1959
    public List<List<T>> chunk(final int size) {
1960
        return chunk(getIterable(), size, size);
1✔
1961
    }
1962

1963
    public List<List<T>> chunk(final int size, final int step) {
1964
        return chunk(getIterable(), size, step);
1✔
1965
    }
1966

1967
    public List<List<T>> chunkFill(final int size, final T fillvalue) {
1968
        return chunkFill(getIterable(), size, size, fillvalue);
1✔
1969
    }
1970

1971
    public List<List<T>> chunkFill(final int size, final int step, T fillvalue) {
1972
        return chunkFill(getIterable(), size, step, fillvalue);
1✔
1973
    }
1974

1975
    public static <T> List<T> cycle(final Iterable<T> iterable, final int times) {
1976
        int size = Math.abs(size(iterable) * times);
1✔
1977
        if (size == 0) {
1✔
1978
            return newArrayList();
1✔
1979
        }
1980
        List<T> list = newArrayListWithExpectedSize(size);
1✔
1981
        int round = 0;
1✔
1982
        if (times > 0) {
1✔
1983
            while (round < times) {
1✔
1984
                for (T element : iterable) {
1✔
1985
                    list.add(element);
1✔
1986
                }
1✔
1987
                round++;
1✔
1988
            }
1989
        } else {
1990
            list = cycle(Underscore.reverse(iterable), -times);
1✔
1991
        }
1992
        return list;
1✔
1993
    }
1994

1995
    public List<T> cycle(final int times) {
1996
        return cycle(value(), times);
1✔
1997
    }
1998

1999
    public static <T> List<T> repeat(final T element, final int times) {
2000
        if (times <= 0) {
1✔
2001
            return newArrayList();
1✔
2002
        }
2003
        List<T> result = newArrayListWithExpectedSize(times);
1✔
2004
        for (int i = 0; i < times; i++) {
1✔
2005
            result.add(element);
1✔
2006
        }
2007
        return result;
1✔
2008
    }
2009

2010
    public static <T> List<T> interpose(final Iterable<T> iterable, final T interElement) {
2011
        if (interElement == null) {
1✔
2012
            return newArrayList(iterable);
1✔
2013
        }
2014
        int size = size(iterable);
1✔
2015
        int index = 0;
1✔
2016
        List<T> array = newArrayListWithExpectedSize(size * 2);
1✔
2017
        for (T elem : iterable) {
1✔
2018
            array.add(elem);
1✔
2019
            if (index + 1 < size) {
1✔
2020
                array.add(interElement);
1✔
2021
                index++;
1✔
2022
            }
2023
        }
1✔
2024
        return array;
1✔
2025
    }
2026

2027
    public static <T> List<T> interposeByList(
2028
            final Iterable<T> iterable, final Iterable<T> interIter) {
2029
        if (interIter == null) {
1✔
2030
            return newArrayList(iterable);
1✔
2031
        }
2032
        List<T> interList = newArrayList(interIter);
1✔
2033
        if (isEmpty(interIter)) {
1✔
2034
            return newArrayList(iterable);
1✔
2035
        }
2036
        int size = size(iterable);
1✔
2037
        List<T> array = newArrayListWithExpectedSize(size + interList.size());
1✔
2038
        int index = 0;
1✔
2039
        for (T element : iterable) {
1✔
2040
            array.add(element);
1✔
2041
            if (index < interList.size() && index + 1 < size) {
1✔
2042
                array.add(interList.get(index));
1✔
2043
                index++;
1✔
2044
            }
2045
        }
1✔
2046
        return array;
1✔
2047
    }
2048

2049
    public List<T> interpose(final T element) {
2050
        return interpose(value(), element);
1✔
2051
    }
2052

2053
    public List<T> interposeByList(final Iterable<T> interIter) {
2054
        return interposeByList(value(), interIter);
1✔
2055
    }
2056

2057
    /*
2058
     * Documented, #bind
2059
     */
2060
    public static <T, F> Function<F, T> bind(final Function<F, T> function) {
2061
        return function;
1✔
2062
    }
2063

2064
    /*
2065
     * Documented, #memoize
2066
     */
2067
    public static <T, F> Function<F, T> memoize(final Function<F, T> function) {
2068
        return new MemoizeFunction<>() {
1✔
2069
            @Override
2070
            public T calc(F arg) {
2071
                return function.apply(arg);
1✔
2072
            }
2073
        };
2074
    }
2075

2076
    /*
2077
     * Documented, #delay
2078
     */
2079
    public static <T> java.util.concurrent.ScheduledFuture<T> delay(
2080
            final Supplier<T> function, final int delayMilliseconds) {
2081
        final java.util.concurrent.ScheduledExecutorService scheduler =
2082
                java.util.concurrent.Executors.newSingleThreadScheduledExecutor();
1✔
2083
        final java.util.concurrent.ScheduledFuture<T> future =
1✔
2084
                scheduler.schedule(
1✔
2085
                        function::get,
1✔
2086
                        delayMilliseconds,
2087
                        java.util.concurrent.TimeUnit.MILLISECONDS);
2088
        scheduler.shutdown();
1✔
2089
        return future;
1✔
2090
    }
2091

2092
    public static <T> java.util.concurrent.ScheduledFuture<T> defer(final Supplier<T> function) {
2093
        return delay(function, 0);
1✔
2094
    }
2095

2096
    public static java.util.concurrent.ScheduledFuture<Void> defer(final Runnable runnable) {
2097
        return delay(
1✔
2098
                () -> {
2099
                    runnable.run();
1✔
2100
                    return null;
1✔
2101
                },
2102
                0);
2103
    }
2104

2105
    public static <T> Supplier<T> throttle(final Supplier<T> function, final int waitMilliseconds) {
2106
        class ThrottleLater implements Supplier<T> {
2107
            private final Supplier<T> localFunction;
2108
            private java.util.concurrent.ScheduledFuture<T> timeout;
2109
            private long previous;
2110

2111
            ThrottleLater(final Supplier<T> function) {
1✔
2112
                this.localFunction = function;
1✔
2113
            }
1✔
2114

2115
            @Override
2116
            public T get() {
2117
                previous = now();
1✔
2118
                timeout = null;
1✔
2119
                return localFunction.get();
1✔
2120
            }
2121

2122
            java.util.concurrent.ScheduledFuture<T> getTimeout() {
2123
                return timeout;
1✔
2124
            }
2125

2126
            void setTimeout(java.util.concurrent.ScheduledFuture<T> timeout) {
2127
                this.timeout = timeout;
1✔
2128
            }
1✔
2129

2130
            long getPrevious() {
2131
                return previous;
1✔
2132
            }
2133

2134
            void setPrevious(long previous) {
2135
                this.previous = previous;
1✔
2136
            }
1✔
2137
        }
2138

2139
        class ThrottleFunction implements Supplier<T> {
2140
            private final Supplier<T> localFunction;
2141
            private final ThrottleLater throttleLater;
2142

2143
            ThrottleFunction(final Supplier<T> function) {
1✔
2144
                this.localFunction = function;
1✔
2145
                this.throttleLater = new ThrottleLater(function);
1✔
2146
            }
1✔
2147

2148
            @Override
2149
            public T get() {
2150
                final long now = now();
1✔
2151
                if (throttleLater.getPrevious() == 0L) {
1✔
2152
                    throttleLater.setPrevious(now);
1✔
2153
                }
2154
                final long remaining = waitMilliseconds - (now - throttleLater.getPrevious());
1✔
2155
                T result = null;
1✔
2156
                if (remaining <= 0) {
1✔
2157
                    throttleLater.setPrevious(now);
1✔
2158
                    result = localFunction.get();
1✔
2159
                } else if (throttleLater.getTimeout() == null) {
1✔
2160
                    throttleLater.setTimeout(delay(throttleLater, waitMilliseconds));
1✔
2161
                }
2162
                return result;
1✔
2163
            }
2164
        }
2165
        return new ThrottleFunction(function);
1✔
2166
    }
2167

2168
    /*
2169
     * Documented, #debounce
2170
     */
2171
    public static <T> Supplier<T> debounce(
2172
            final Supplier<T> function, final int delayMilliseconds) {
2173
        return new Supplier<>() {
1✔
2174
            private java.util.concurrent.ScheduledFuture<T> timeout;
2175

2176
            @Override
2177
            public T get() {
2178
                clearTimeout(timeout);
1✔
2179
                timeout = delay(function, delayMilliseconds);
1✔
2180
                return null;
1✔
2181
            }
2182
        };
2183
    }
2184

2185
    /*
2186
     * Documented, #wrap
2187
     */
2188
    public static <T> Function<Void, T> wrap(
2189
            final UnaryOperator<T> function, final Function<UnaryOperator<T>, T> wrapper) {
2190
        return arg -> wrapper.apply(function);
1✔
2191
    }
2192

2193
    public static <E> Predicate<E> negate(final Predicate<E> pred) {
2194
        return item -> !pred.test(item);
1✔
2195
    }
2196

2197
    /*
2198
     * Documented, #compose
2199
     */
2200
    @SuppressWarnings("unchecked")
2201
    public static <T> Function<T, T> compose(final Function<T, T>... func) {
2202
        return arg -> {
1✔
2203
            T result = arg;
1✔
2204
            for (int index = func.length - 1; index >= 0; index -= 1) {
1✔
2205
                result = func[index].apply(result);
1✔
2206
            }
2207
            return result;
1✔
2208
        };
2209
    }
2210

2211
    /*
2212
     * Documented, #after
2213
     */
2214
    public static <E> Supplier<E> after(final int count, final Supplier<E> function) {
2215
        class AfterFunction implements Supplier<E> {
2216
            private final int count;
2217
            private final Supplier<E> localFunction;
2218
            private int index;
2219
            private E result;
2220

2221
            AfterFunction(final int count, final Supplier<E> function) {
1✔
2222
                this.count = count;
1✔
2223
                this.localFunction = function;
1✔
2224
            }
1✔
2225

2226
            public E get() {
2227
                if (++index >= count) {
1✔
2228
                    result = localFunction.get();
1✔
2229
                }
2230
                return result;
1✔
2231
            }
2232
        }
2233
        return new AfterFunction(count, function);
1✔
2234
    }
2235

2236
    /*
2237
     * Documented, #before
2238
     */
2239
    public static <E> Supplier<E> before(final int count, final Supplier<E> function) {
2240
        class BeforeFunction implements Supplier<E> {
2241
            private final int count;
2242
            private final Supplier<E> localFunction;
2243
            private int index;
2244
            private E result;
2245

2246
            BeforeFunction(final int count, final Supplier<E> function) {
1✔
2247
                this.count = count;
1✔
2248
                this.localFunction = function;
1✔
2249
            }
1✔
2250

2251
            public E get() {
2252
                if (++index <= count) {
1✔
2253
                    result = localFunction.get();
1✔
2254
                }
2255
                return result;
1✔
2256
            }
2257
        }
2258
        return new BeforeFunction(count, function);
1✔
2259
    }
2260

2261
    /*
2262
     * Documented, #once
2263
     */
2264
    public static <T> Supplier<T> once(final Supplier<T> function) {
2265
        return new Supplier<>() {
1✔
2266
            private volatile boolean executed;
2267
            private T result;
2268

2269
            @Override
2270
            public T get() {
2271
                if (!executed) {
1✔
2272
                    executed = true;
1✔
2273
                    result = function.get();
1✔
2274
                }
2275
                return result;
1✔
2276
            }
2277
        };
2278
    }
2279

2280
    /*
2281
     * Documented, #keys
2282
     */
2283
    public static <K, V> Set<K> keys(final Map<K, V> object) {
2284
        return object.keySet();
1✔
2285
    }
2286

2287
    /*
2288
     * Documented, #values
2289
     */
2290
    public static <K, V> Collection<V> values(final Map<K, V> object) {
2291
        return object.values();
1✔
2292
    }
2293

2294
    public static <K, V> List<Map.Entry<K, V>> mapObject(
2295
            final Map<K, V> object, final Function<? super V, V> func) {
2296
        return map(
1✔
2297
                newArrayList(object.entrySet()),
1✔
2298
                entry -> Map.entry(entry.getKey(), func.apply(entry.getValue())));
1✔
2299
    }
2300

2301
    /*
2302
     * Documented, #pairs
2303
     */
2304
    public static <K, V> List<Map.Entry<K, V>> pairs(final Map<K, V> object) {
2305
        return map(
1✔
2306
                newArrayList(object.entrySet()),
1✔
2307
                entry -> Map.entry(entry.getKey(), entry.getValue()));
1✔
2308
    }
2309

2310
    /*
2311
     * Documented, #invert
2312
     */
2313
    public static <K, V> List<Map.Entry<V, K>> invert(final Map<K, V> object) {
2314
        return map(
1✔
2315
                newArrayList(object.entrySet()),
1✔
2316
                entry -> Map.entry(entry.getValue(), entry.getKey()));
1✔
2317
    }
2318

2319
    /*
2320
     * Documented, #functions
2321
     */
2322
    public static List<String> functions(final Object object) {
2323
        final List<String> result = newArrayList();
1✔
2324
        for (final Method method : object.getClass().getDeclaredMethods()) {
1✔
2325
            result.add(method.getName());
1✔
2326
        }
2327
        return sort(uniq(result));
1✔
2328
    }
2329

2330
    public static List<String> methods(final Object object) {
2331
        return functions(object);
1✔
2332
    }
2333

2334
    /*
2335
     * Documented, #extend
2336
     */
2337
    @SuppressWarnings("unchecked")
2338
    public static <K, V> Map<K, V> extend(final Map<K, V> destination, final Map<K, V>... sources) {
2339
        final Map<K, V> result = newLinkedHashMap();
1✔
2340
        result.putAll(destination);
1✔
2341
        for (final Map<K, V> source : sources) {
1✔
2342
            result.putAll(source);
1✔
2343
        }
2344
        return result;
1✔
2345
    }
2346

2347
    public static <E> E findKey(final List<E> list, final Predicate<E> pred) {
2348
        for (E e : list) {
1✔
2349
            if (pred.test(e)) {
1✔
2350
                return e;
1✔
2351
            }
2352
        }
1✔
2353
        return null;
1✔
2354
    }
2355

2356
    public static <E> E findKey(final E[] array, final Predicate<E> pred) {
2357
        return findKey(Arrays.asList(array), pred);
1✔
2358
    }
2359

2360
    public static <E> E findLastKey(final List<E> list, final Predicate<E> pred) {
2361
        for (int index = list.size() - 1; index >= 0; index--) {
1✔
2362
            if (pred.test(list.get(index))) {
1✔
2363
                return list.get(index);
1✔
2364
            }
2365
        }
2366
        return null;
1✔
2367
    }
2368

2369
    public static <E> E findLastKey(final E[] array, final Predicate<E> pred) {
2370
        return findLastKey(Arrays.asList(array), pred);
1✔
2371
    }
2372

2373
    /*
2374
     * Documented, #pick
2375
     */
2376
    @SuppressWarnings("unchecked")
2377
    public static <K, V> List<Map.Entry<K, V>> pick(final Map<K, V> object, final K... keys) {
2378
        return without(
1✔
2379
                map(
1✔
2380
                        newArrayList(object.entrySet()),
1✔
2381
                        entry -> {
2382
                            if (Arrays.asList(keys).contains(entry.getKey())) {
1✔
2383
                                return Map.entry(entry.getKey(), entry.getValue());
1✔
2384
                            } else {
2385
                                return null;
1✔
2386
                            }
2387
                        }),
2388
                (Map.Entry<K, V>) null);
2389
    }
2390

2391
    @SuppressWarnings("unchecked")
2392
    public static <K, V> List<Map.Entry<K, V>> pick(
2393
            final Map<K, V> object, final Predicate<V> pred) {
2394
        return without(
1✔
2395
                map(
1✔
2396
                        newArrayList(object.entrySet()),
1✔
2397
                        entry -> {
2398
                            if (pred.test(object.get(entry.getKey()))) {
1✔
2399
                                return Map.entry(entry.getKey(), entry.getValue());
1✔
2400
                            } else {
2401
                                return null;
1✔
2402
                            }
2403
                        }),
2404
                (Map.Entry<K, V>) null);
2405
    }
2406

2407
    /*
2408
     * Documented, #omit
2409
     */
2410
    @SuppressWarnings("unchecked")
2411
    public static <K, V> List<Map.Entry<K, V>> omit(final Map<K, V> object, final K... keys) {
2412
        return without(
1✔
2413
                map(
1✔
2414
                        newArrayList(object.entrySet()),
1✔
2415
                        entry -> {
2416
                            if (Arrays.asList(keys).contains(entry.getKey())) {
1✔
2417
                                return null;
1✔
2418
                            } else {
2419
                                return Map.entry(entry.getKey(), entry.getValue());
1✔
2420
                            }
2421
                        }),
2422
                (Map.Entry<K, V>) null);
2423
    }
2424

2425
    @SuppressWarnings("unchecked")
2426
    public static <K, V> List<Map.Entry<K, V>> omit(
2427
            final Map<K, V> object, final Predicate<V> pred) {
2428
        return without(
1✔
2429
                map(
1✔
2430
                        newArrayList(object.entrySet()),
1✔
2431
                        entry -> {
2432
                            if (pred.test(entry.getValue())) {
1✔
2433
                                return null;
1✔
2434
                            } else {
2435
                                return Map.entry(entry.getKey(), entry.getValue());
1✔
2436
                            }
2437
                        }),
2438
                (Map.Entry<K, V>) null);
2439
    }
2440

2441
    /*
2442
     * Documented, #defaults
2443
     */
2444
    public static <K, V> Map<K, V> defaults(final Map<K, V> object, final Map<K, V> defaults) {
2445
        final Map<K, V> result = newLinkedHashMap();
1✔
2446
        result.putAll(defaults);
1✔
2447
        result.putAll(object);
1✔
2448
        return result;
1✔
2449
    }
2450

2451
    /*
2452
     * Documented, #clone
2453
     */
2454
    public static Object clone(final Object obj) {
2455
        try {
2456
            if (obj instanceof Cloneable) {
1✔
2457
                for (final Method method : obj.getClass().getMethods()) {
1✔
2458
                    if (method.getName().equals("clone")
1✔
2459
                            && method.getParameterTypes().length == 0) {
1✔
2460
                        return method.invoke(obj);
1✔
2461
                    }
2462
                }
2463
            }
2464
        } catch (Exception e) {
1✔
2465
            throw new IllegalArgumentException(e);
1✔
2466
        }
1✔
2467
        throw new IllegalArgumentException("Cannot clone object");
1✔
2468
    }
2469

2470
    @SuppressWarnings("unchecked")
2471
    public static <E> E[] clone(final E... iterable) {
2472
        return Arrays.copyOf(iterable, iterable.length);
1✔
2473
    }
2474

2475
    public static <T> void tap(final Iterable<T> iterable, final Consumer<? super T> func) {
2476
        each(iterable, func);
1✔
2477
    }
1✔
2478

2479
    public static <K, V> boolean isMatch(final Map<K, V> object, final Map<K, V> properties) {
2480
        for (final K key : keys(properties)) {
1✔
2481
            if (!object.containsKey(key) || !object.get(key).equals(properties.get(key))) {
1✔
2482
                return false;
1✔
2483
            }
2484
        }
1✔
2485
        return true;
1✔
2486
    }
2487

2488
    /*
2489
     * Documented, #isEqual
2490
     */
2491
    public static boolean isEqual(final Object object, final Object other) {
2492
        return Objects.equals(object, other);
1✔
2493
    }
2494

2495
    public static <K, V> boolean isEmpty(final Map<K, V> object) {
2496
        return object == null || object.isEmpty();
1✔
2497
    }
2498

2499
    /*
2500
     * Documented, #isEmpty
2501
     */
2502
    public static <T> boolean isEmpty(final Iterable<T> iterable) {
2503
        return iterable == null || !iterable.iterator().hasNext();
1✔
2504
    }
2505

2506
    public boolean isEmpty() {
2507
        return iterable == null || !iterable.iterator().hasNext();
1✔
2508
    }
2509

2510
    public static <K, V> boolean isNotEmpty(final Map<K, V> object) {
2511
        return object != null && !object.isEmpty();
1✔
2512
    }
2513

2514
    public static <T> boolean isNotEmpty(final Iterable<T> iterable) {
2515
        return iterable != null && iterable.iterator().hasNext();
1✔
2516
    }
2517

2518
    public boolean isNotEmpty() {
2519
        return iterable != null && iterable.iterator().hasNext();
1✔
2520
    }
2521

2522
    /*
2523
     * Documented, #isArray
2524
     */
2525
    public static boolean isArray(final Object object) {
2526
        return object != null && object.getClass().isArray();
1✔
2527
    }
2528

2529
    /*
2530
     * Documented, #isObject
2531
     */
2532
    public static boolean isObject(final Object object) {
2533
        return object instanceof Map;
1✔
2534
    }
2535

2536
    /*
2537
     * Documented, #isFunction
2538
     */
2539
    public static boolean isFunction(final Object object) {
2540
        return object instanceof Function;
1✔
2541
    }
2542

2543
    /*
2544
     * Documented, #isString
2545
     */
2546
    public static boolean isString(final Object object) {
2547
        return object instanceof String;
1✔
2548
    }
2549

2550
    /*
2551
     * Documented, #isNumber
2552
     */
2553
    public static boolean isNumber(final Object object) {
2554
        return object instanceof Number;
1✔
2555
    }
2556

2557
    /*
2558
     * Documented, #isDate
2559
     */
2560
    public static boolean isDate(final Object object) {
2561
        return object instanceof Date;
1✔
2562
    }
2563

2564
    public static boolean isRegExp(final Object object) {
2565
        return object instanceof java.util.regex.Pattern;
1✔
2566
    }
2567

2568
    public static boolean isError(final Object object) {
2569
        return object instanceof Throwable;
1✔
2570
    }
2571

2572
    /*
2573
     * Documented, #isBoolean
2574
     */
2575
    public static boolean isBoolean(final Object object) {
2576
        return object instanceof Boolean;
1✔
2577
    }
2578

2579
    public static boolean isNull(final Object object) {
2580
        return object == null;
1✔
2581
    }
2582

2583
    /*
2584
     * Documented, #has
2585
     */
2586
    public static <K, V> boolean has(final Map<K, V> object, final K key) {
2587
        return object.containsKey(key);
1✔
2588
    }
2589

2590
    public static <E> E identity(final E value) {
2591
        return value;
1✔
2592
    }
2593

2594
    public static <E> Supplier<E> constant(final E value) {
2595
        return () -> value;
1✔
2596
    }
2597

2598
    public static <K, V> Function<Map<K, V>, V> property(final K key) {
2599
        return object -> object.get(key);
1✔
2600
    }
2601

2602
    public static <K, V> Function<K, V> propertyOf(final Map<K, V> object) {
2603
        return object::get;
1✔
2604
    }
2605

2606
    public static <K, V> Predicate<Map<K, V>> matcher(final Map<K, V> object) {
2607
        return item -> {
1✔
2608
            for (final K key : keys(object)) {
1✔
2609
                if (!item.containsKey(key) || !item.get(key).equals(object.get(key))) {
1✔
2610
                    return false;
1✔
2611
                }
2612
            }
1✔
2613
            return true;
1✔
2614
        };
2615
    }
2616

2617
    /*
2618
     * Documented, #times
2619
     */
2620
    public static void times(final int count, final Runnable runnable) {
2621
        for (int index = 0; index < count; index += 1) {
1✔
2622
            runnable.run();
1✔
2623
        }
2624
    }
1✔
2625

2626
    /*
2627
     * Documented, #random
2628
     */
2629
    public static int random(final int min, final int max) {
2630
        return min + new java.security.SecureRandom().nextInt(max - min + 1);
1✔
2631
    }
2632

2633
    public static int random(final int max) {
2634
        return new java.security.SecureRandom().nextInt(max + 1);
1✔
2635
    }
2636

2637
    public static long now() {
2638
        return new Date().getTime();
1✔
2639
    }
2640

2641
    /*
2642
     * Documented, #escape
2643
     */
2644
    public static String escape(final String value) {
2645
        final StringBuilder builder = new StringBuilder();
1✔
2646
        for (final char ch : value.toCharArray()) {
1✔
2647
            builder.append(ESCAPES.containsKey(ch) ? ESCAPES.get(ch) : ch);
1✔
2648
        }
2649
        return builder.toString();
1✔
2650
    }
2651

2652
    public static String unescape(final String value) {
2653
        return value.replace("&#x60;", "`")
1✔
2654
                .replace("&#x27;", "'")
1✔
2655
                .replace("&lt;", "<")
1✔
2656
                .replace("&gt;", ">")
1✔
2657
                .replace("&quot;", "\"")
1✔
2658
                .replace("&amp;", "&");
1✔
2659
    }
2660

2661
    /*
2662
     * Documented, #result
2663
     */
2664
    public static <E> Object result(final Iterable<E> iterable, final Predicate<E> pred) {
2665
        for (E element : iterable) {
1✔
2666
            if (pred.test(element)) {
1✔
2667
                if (element instanceof Map.Entry) {
1✔
2668
                    if (((Map.Entry) element).getValue() instanceof Supplier) {
1✔
2669
                        return ((Supplier) ((Map.Entry) element).getValue()).get();
1✔
2670
                    }
2671
                    return ((Map.Entry) element).getValue();
1✔
2672
                }
2673
                return element;
1✔
2674
            }
2675
        }
1✔
2676
        return null;
1✔
2677
    }
2678

2679
    /*
2680
     * Documented, #uniqueId
2681
     */
2682
    public static String uniqueId(final String prefix) {
2683
        return (prefix == null ? "" : prefix) + UNIQUE_ID.incrementAndGet();
1✔
2684
    }
2685

2686
    /*
2687
     * Documented, #uniquePassword
2688
     */
2689
    public static String uniquePassword() {
2690
        final String[] passwords =
1✔
2691
                new String[] {
2692
                    "ALKJVBPIQYTUIWEBVPQALZVKQRWORTUYOYISHFLKAJMZNXBVMNFGAHKJSDFALAPOQIERIUYTGSFGKMZNXBVJAHGFAKX",
2693
                    "1234567890",
2694
                    "qpowiealksdjzmxnvbfghsdjtreiuowiruksfhksajmzxncbvlaksjdhgqwetytopskjhfgvbcnmzxalksjdfhgbvzm",
2695
                    ".@,-+/()#$%^&*!"
2696
                };
2697
        final StringBuilder result = new StringBuilder();
1✔
2698
        final long passwordLength =
2699
                Math.abs(UUID.randomUUID().getLeastSignificantBits() % MIN_PASSWORD_LENGTH_8)
1✔
2700
                        + MIN_PASSWORD_LENGTH_8;
2701
        for (int index = 0; index < passwordLength; index += 1) {
1✔
2702
            final int passIndex = (int) (passwords.length * (long) index / passwordLength);
1✔
2703
            final int charIndex =
2704
                    (int)
2705
                            Math.abs(
1✔
2706
                                    UUID.randomUUID().getLeastSignificantBits()
1✔
2707
                                            % passwords[passIndex].length());
1✔
2708
            result.append(passwords[passIndex].charAt(charIndex));
1✔
2709
        }
2710
        return result.toString();
1✔
2711
    }
2712

2713
    public static <K, V> Template<Map<K, V>> template(final String template) {
2714
        return new TemplateImpl<>(template);
1✔
2715
    }
2716

2717
    public static String format(final String template, final Object... params) {
2718
        final java.util.regex.Matcher matcher = FORMAT_PATTERN.matcher(template);
1✔
2719
        final StringBuffer buffer = new StringBuffer();
1✔
2720
        int index = 0;
1✔
2721
        while (matcher.find()) {
1✔
2722
            if (matcher.group(1).isEmpty()) {
1✔
2723
                matcher.appendReplacement(buffer, "<%" + index++ + "%>");
1✔
2724
            } else {
2725
                matcher.appendReplacement(buffer, "<%" + matcher.group(1) + "%>");
1✔
2726
            }
2727
        }
2728
        matcher.appendTail(buffer);
1✔
2729
        final String newTemplate = buffer.toString();
1✔
2730
        final Map<Integer, String> args = newLinkedHashMap();
1✔
2731
        index = 0;
1✔
2732
        for (Object param : params) {
1✔
2733
            args.put(index, param.toString());
1✔
2734
            index += 1;
1✔
2735
        }
2736
        return new TemplateImpl<Integer, String>(newTemplate).apply(args);
1✔
2737
    }
2738

2739
    public static <T> Iterable<T> iterate(final T seed, final UnaryOperator<T> unaryOperator) {
2740
        return new MyIterable<>(seed, unaryOperator);
1✔
2741
    }
2742

2743
    /*
2744
     * Documented, #chain
2745
     */
2746
    public static <T> Chain<T> chain(final List<T> list) {
2747
        return new Underscore.Chain<>(list);
1✔
2748
    }
2749

2750
    public static Chain<Map<String, Object>> chain(final Map<String, Object> map) {
2751
        return new Underscore.Chain<>(map);
1✔
2752
    }
2753

2754
    public static <T> Chain<T> chain(final Iterable<T> iterable) {
2755
        return new Underscore.Chain<>(newArrayList(iterable));
1✔
2756
    }
2757

2758
    public static <T> Chain<T> chain(final Iterable<T> iterable, int size) {
2759
        return new Underscore.Chain<>(newArrayList(iterable, size));
1✔
2760
    }
2761

2762
    @SuppressWarnings("unchecked")
2763
    public static <T> Chain<T> chain(final T... array) {
2764
        return new Underscore.Chain<>(Arrays.asList(array));
1✔
2765
    }
2766

2767
    public static Chain<Integer> chain(final int[] array) {
2768
        return new Underscore.Chain<>(newIntegerList(array));
1✔
2769
    }
2770

2771
    public Chain<T> chain() {
2772
        return new Underscore.Chain<>(newArrayList(iterable));
1✔
2773
    }
2774

2775
    public static <T> Chain<T> of(final List<T> list) {
2776
        return new Underscore.Chain<>(list);
1✔
2777
    }
2778

2779
    public static <T> Chain<T> of(final Iterable<T> iterable) {
2780
        return new Underscore.Chain<>(newArrayList(iterable));
1✔
2781
    }
2782

2783
    public static <T> Chain<T> of(final Iterable<T> iterable, int size) {
2784
        return new Underscore.Chain<>(newArrayList(iterable, size));
1✔
2785
    }
2786

2787
    @SuppressWarnings("unchecked")
2788
    public static <T> Chain<T> of(final T... array) {
2789
        return new Underscore.Chain<>(Arrays.asList(array));
1✔
2790
    }
2791

2792
    public static Chain<Integer> of(final int[] array) {
2793
        return new Underscore.Chain<>(newIntegerList(array));
1✔
2794
    }
2795

2796
    public Chain<T> of() {
2797
        return new Underscore.Chain<>(newArrayList(iterable));
1✔
2798
    }
2799

2800
    public static class Chain<T> {
2801
        private final T item;
2802
        private final List<T> list;
2803
        private final Map<String, Object> map;
2804

2805
        public Chain(final T item) {
1✔
2806
            this.item = item;
1✔
2807
            this.list = null;
1✔
2808
            this.map = null;
1✔
2809
        }
1✔
2810

2811
        public Chain(final List<T> list) {
1✔
2812
            this.item = null;
1✔
2813
            this.list = list;
1✔
2814
            this.map = null;
1✔
2815
        }
1✔
2816

2817
        public Chain(final Map<String, Object> map) {
1✔
2818
            this.item = null;
1✔
2819
            this.list = null;
1✔
2820
            this.map = map;
1✔
2821
        }
1✔
2822

2823
        public Chain<T> first() {
2824
            return new Chain<>(Underscore.first(list));
1✔
2825
        }
2826

2827
        public Chain<T> first(int n) {
2828
            return new Chain<>(Underscore.first(list, n));
1✔
2829
        }
2830

2831
        public Chain<T> first(final Predicate<T> pred) {
2832
            return new Chain<>(Underscore.first(list, pred));
1✔
2833
        }
2834

2835
        public Chain<T> first(final Predicate<T> pred, int n) {
2836
            return new Chain<>(Underscore.first(list, pred, n));
1✔
2837
        }
2838

2839
        public Chain<T> firstOrNull() {
2840
            return new Chain<>(Underscore.firstOrNull(list));
1✔
2841
        }
2842

2843
        public Chain<T> firstOrNull(final Predicate<T> pred) {
2844
            return new Chain<>(Underscore.firstOrNull(list, pred));
1✔
2845
        }
2846

2847
        public Chain<T> initial() {
2848
            return new Chain<>(Underscore.initial(list));
1✔
2849
        }
2850

2851
        public Chain<T> initial(int n) {
2852
            return new Chain<>(Underscore.initial(list, n));
1✔
2853
        }
2854

2855
        public Chain<T> last() {
2856
            return new Chain<>(Underscore.last(list));
1✔
2857
        }
2858

2859
        public Chain<T> last(int n) {
2860
            return new Chain<>(Underscore.last(list, n));
1✔
2861
        }
2862

2863
        public Chain<T> lastOrNull() {
2864
            return new Chain<>(Underscore.lastOrNull(list));
1✔
2865
        }
2866

2867
        public Chain<T> lastOrNull(final Predicate<T> pred) {
2868
            return new Chain<>(Underscore.lastOrNull(list, pred));
1✔
2869
        }
2870

2871
        public Chain<T> rest() {
2872
            return new Chain<>(Underscore.rest(list));
1✔
2873
        }
2874

2875
        public Chain<T> rest(int n) {
2876
            return new Chain<>(Underscore.rest(list, n));
1✔
2877
        }
2878

2879
        public Chain<T> compact() {
2880
            return new Chain<>(Underscore.compact(list));
1✔
2881
        }
2882

2883
        public Chain<T> compact(final T falsyValue) {
2884
            return new Chain<>(Underscore.compact(list, falsyValue));
1✔
2885
        }
2886

2887
        @SuppressWarnings("unchecked")
2888
        public Chain flatten() {
2889
            return new Chain<>(Underscore.flatten(list));
1✔
2890
        }
2891

2892
        public <F> Chain<F> map(final Function<? super T, F> func) {
2893
            return new Chain<>(Underscore.map(list, func));
1✔
2894
        }
2895

2896
        public <F> Chain<F> mapMulti(final BiConsumer<? super T, ? super Consumer<F>> mapper) {
2897
            return new Chain<>(Underscore.mapMulti(list, mapper));
1✔
2898
        }
2899

2900
        public <F> Chain<F> mapIndexed(final BiFunction<Integer, ? super T, F> func) {
2901
            return new Chain<>(Underscore.mapIndexed(list, func));
1✔
2902
        }
2903

2904
        public Chain<T> replace(final Predicate<T> pred, final T value) {
2905
            return new Chain<>(Underscore.replace(list, pred, value));
1✔
2906
        }
2907

2908
        public Chain<T> replaceIndexed(final PredicateIndexed<T> pred, final T value) {
2909
            return new Chain<>(Underscore.replaceIndexed(list, pred, value));
1✔
2910
        }
2911

2912
        public Chain<T> filter(final Predicate<T> pred) {
2913
            return new Chain<>(Underscore.filter(list, pred));
1✔
2914
        }
2915

2916
        public Chain<T> filterIndexed(final PredicateIndexed<T> pred) {
2917
            return new Chain<>(Underscore.filterIndexed(list, pred));
1✔
2918
        }
2919

2920
        public Chain<T> reject(final Predicate<T> pred) {
2921
            return new Chain<>(Underscore.reject(list, pred));
1✔
2922
        }
2923

2924
        public Chain<T> rejectIndexed(final PredicateIndexed<T> pred) {
2925
            return new Chain<>(Underscore.rejectIndexed(list, pred));
1✔
2926
        }
2927

2928
        public Chain<T> filterFalse(final Predicate<T> pred) {
2929
            return new Chain<>(Underscore.reject(list, pred));
1✔
2930
        }
2931

2932
        public <F> Chain<F> reduce(final BiFunction<F, T, F> func, final F zeroElem) {
2933
            return new Chain<>(Underscore.reduce(list, func, zeroElem));
1✔
2934
        }
2935

2936
        public Chain<Optional<T>> reduce(final BinaryOperator<T> func) {
2937
            return new Chain<>(Underscore.reduce(list, func));
1✔
2938
        }
2939

2940
        public <F> Chain<F> reduceRight(final BiFunction<F, T, F> func, final F zeroElem) {
2941
            return new Chain<>(Underscore.reduceRight(list, func, zeroElem));
1✔
2942
        }
2943

2944
        public Chain<Optional<T>> reduceRight(final BinaryOperator<T> func) {
2945
            return new Chain<>(Underscore.reduceRight(list, func));
1✔
2946
        }
2947

2948
        public Chain<Optional<T>> find(final Predicate<T> pred) {
2949
            return new Chain<>(Underscore.find(list, pred));
1✔
2950
        }
2951

2952
        public Chain<Optional<T>> findLast(final Predicate<T> pred) {
2953
            return new Chain<>(Underscore.findLast(list, pred));
1✔
2954
        }
2955

2956
        @SuppressWarnings("unchecked")
2957
        public Chain<Comparable> max() {
2958
            return new Chain<>(Underscore.max((Collection) list));
1✔
2959
        }
2960

2961
        public <F extends Comparable<? super F>> Chain<T> max(final Function<T, F> func) {
2962
            return new Chain<>(Underscore.max(list, func));
1✔
2963
        }
2964

2965
        @SuppressWarnings("unchecked")
2966
        public Chain<Comparable> min() {
2967
            return new Chain<>(Underscore.min((Collection) list));
1✔
2968
        }
2969

2970
        public <F extends Comparable<? super F>> Chain<T> min(final Function<T, F> func) {
2971
            return new Chain<>(Underscore.min(list, func));
1✔
2972
        }
2973

2974
        @SuppressWarnings("unchecked")
2975
        public Chain<Comparable> sort() {
2976
            return new Chain<>(Underscore.sort((List<Comparable>) list));
1✔
2977
        }
2978

2979
        @SuppressWarnings("unchecked")
2980
        public <F extends Comparable<? super F>> Chain<F> sortWith(final Comparator<F> comparator) {
2981
            return new Chain<>(Underscore.sortWith((List<F>) list, comparator));
1✔
2982
        }
2983

2984
        public <F extends Comparable<? super F>> Chain<T> sortBy(final Function<T, F> func) {
2985
            return new Chain<>(Underscore.sortBy(list, func));
1✔
2986
        }
2987

2988
        @SuppressWarnings("unchecked")
2989
        public <K> Chain<Map<K, Comparable>> sortBy(final K key) {
2990
            return new Chain<>(Underscore.sortBy((List<Map<K, Comparable>>) list, key));
1✔
2991
        }
2992

2993
        public <F> Chain<Map<F, List<T>>> groupBy(final Function<T, F> func) {
2994
            return new Chain<>(Underscore.groupBy(list, func));
1✔
2995
        }
2996

2997
        public <F> Chain<Map<F, Optional<T>>> groupBy(
2998
                final Function<T, F> func, final BinaryOperator<T> binaryOperator) {
2999
            return new Chain<>(Underscore.groupBy(list, func, binaryOperator));
1✔
3000
        }
3001

3002
        public Chain<Map<Object, List<T>>> indexBy(final String property) {
3003
            return new Chain<>(Underscore.indexBy(list, property));
1✔
3004
        }
3005

3006
        public <F> Chain<Map<F, Integer>> countBy(final Function<T, F> func) {
3007
            return new Chain<>(Underscore.countBy(list, func));
1✔
3008
        }
3009

3010
        public Chain<Map<T, Integer>> countBy() {
3011
            return new Chain<>(Underscore.countBy(list));
1✔
3012
        }
3013

3014
        public Chain<T> shuffle() {
3015
            return new Chain<>(Underscore.shuffle(list));
1✔
3016
        }
3017

3018
        public Chain<T> sample() {
3019
            return new Chain<>(Underscore.sample(list));
1✔
3020
        }
3021

3022
        public Chain<T> sample(final int howMany) {
3023
            return new Chain<>(Underscore.newArrayList(Underscore.sample(list, howMany)));
1✔
3024
        }
3025

3026
        public Chain<T> tap(final Consumer<T> func) {
3027
            Underscore.each(list, func);
1✔
3028
            return new Chain<>(list);
1✔
3029
        }
3030

3031
        public Chain<T> forEach(final Consumer<T> func) {
3032
            return tap(func);
1✔
3033
        }
3034

3035
        public Chain<T> forEachRight(final Consumer<T> func) {
3036
            Underscore.eachRight(list, func);
1✔
3037
            return new Chain<>(list);
1✔
3038
        }
3039

3040
        public Chain<Boolean> every(final Predicate<T> pred) {
3041
            return new Chain<>(Underscore.every(list, pred));
1✔
3042
        }
3043

3044
        public Chain<Boolean> some(final Predicate<T> pred) {
3045
            return new Chain<>(Underscore.some(list, pred));
1✔
3046
        }
3047

3048
        public Chain<Integer> count(final Predicate<T> pred) {
3049
            return new Chain<>(Underscore.count(list, pred));
1✔
3050
        }
3051

3052
        public Chain<Boolean> contains(final T elem) {
3053
            return new Chain<>(Underscore.contains(list, elem));
1✔
3054
        }
3055

3056
        public Chain<Boolean> containsWith(final T elem) {
3057
            return new Chain<>(Underscore.containsWith(list, elem));
1✔
3058
        }
3059

3060
        public Chain<T> invoke(final String methodName, final List<Object> args) {
3061
            return new Chain<>(Underscore.invoke(list, methodName, args));
1✔
3062
        }
3063

3064
        public Chain<T> invoke(final String methodName) {
3065
            return new Chain<>(Underscore.invoke(list, methodName));
1✔
3066
        }
3067

3068
        public Chain<Object> pluck(final String propertyName) {
3069
            return new Chain<>(Underscore.pluck(list, propertyName));
1✔
3070
        }
3071

3072
        public <E> Chain<T> where(final List<Map.Entry<String, E>> properties) {
3073
            return new Chain<>(Underscore.where(list, properties));
1✔
3074
        }
3075

3076
        public <E> Chain<Optional<T>> findWhere(final List<Map.Entry<String, E>> properties) {
3077
            return new Chain<>(Underscore.findWhere(list, properties));
1✔
3078
        }
3079

3080
        public Chain<T> uniq() {
3081
            return new Chain<>(Underscore.uniq(list));
1✔
3082
        }
3083

3084
        public <F> Chain<T> uniq(final Function<T, F> func) {
3085
            return new Chain<>(Underscore.newArrayList(Underscore.uniq(list, func)));
1✔
3086
        }
3087

3088
        public Chain<T> distinct() {
3089
            return new Chain<>(Underscore.uniq(list));
1✔
3090
        }
3091

3092
        @SuppressWarnings("unchecked")
3093
        public <F> Chain<F> distinctBy(final Function<T, F> func) {
3094
            return new Chain<>(Underscore.newArrayList((Iterable<F>) Underscore.uniq(list, func)));
1✔
3095
        }
3096

3097
        @SuppressWarnings("unchecked")
3098
        public Chain<T> union(final List<T>... lists) {
3099
            return new Chain<>(Underscore.union(list, lists));
1✔
3100
        }
3101

3102
        @SuppressWarnings("unchecked")
3103
        public Chain<T> intersection(final List<T>... lists) {
3104
            return new Chain<>(Underscore.intersection(list, lists));
1✔
3105
        }
3106

3107
        @SuppressWarnings("unchecked")
3108
        public Chain<T> difference(final List<T>... lists) {
3109
            return new Chain<>(Underscore.difference(list, lists));
1✔
3110
        }
3111

3112
        public Chain<Integer> range(final int stop) {
3113
            return new Chain<>(Underscore.range(stop));
1✔
3114
        }
3115

3116
        public Chain<Integer> range(final int start, final int stop) {
3117
            return new Chain<>(Underscore.range(start, stop));
1✔
3118
        }
3119

3120
        public Chain<Integer> range(final int start, final int stop, final int step) {
3121
            return new Chain<>(Underscore.range(start, stop, step));
1✔
3122
        }
3123

3124
        public Chain<List<T>> chunk(final int size) {
3125
            return new Chain<>(Underscore.chunk(value(), size, size));
1✔
3126
        }
3127

3128
        public Chain<List<T>> chunk(final int size, final int step) {
3129
            return new Chain<>(Underscore.chunk(value(), size, step));
1✔
3130
        }
3131

3132
        public Chain<List<T>> chunkFill(final int size, final T fillValue) {
3133
            return new Chain<>(Underscore.chunkFill(value(), size, size, fillValue));
1✔
3134
        }
3135

3136
        public Chain<List<T>> chunkFill(final int size, final int step, final T fillValue) {
3137
            return new Chain<>(Underscore.chunkFill(value(), size, step, fillValue));
1✔
3138
        }
3139

3140
        public Chain<T> cycle(final int times) {
3141
            return new Chain<>(Underscore.cycle(value(), times));
1✔
3142
        }
3143

3144
        public Chain<T> interpose(final T element) {
3145
            return new Chain<>(Underscore.interpose(value(), element));
1✔
3146
        }
3147

3148
        public Chain<T> interposeByList(final Iterable<T> interIter) {
3149
            return new Chain<>(Underscore.interposeByList(value(), interIter));
1✔
3150
        }
3151

3152
        @SuppressWarnings("unchecked")
3153
        public Chain<T> concat(final List<T>... lists) {
3154
            return new Chain<>(Underscore.concat(list, lists));
1✔
3155
        }
3156

3157
        public Chain<T> slice(final int start) {
3158
            return new Chain<>(Underscore.slice(list, start));
1✔
3159
        }
3160

3161
        public Chain<T> slice(final int start, final int end) {
3162
            return new Chain<>(Underscore.slice(list, start, end));
1✔
3163
        }
3164

3165
        public Chain<List<T>> splitAt(final int position) {
3166
            return new Chain<>(Underscore.splitAt(list, position));
1✔
3167
        }
3168

3169
        public Chain<T> takeSkipping(final int stepSize) {
3170
            return new Chain<>(Underscore.takeSkipping(list, stepSize));
1✔
3171
        }
3172

3173
        public Chain<T> reverse() {
3174
            return new Chain<>(Underscore.reverse(list));
1✔
3175
        }
3176

3177
        public Chain<String> join() {
3178
            return new Chain<>(Underscore.join(list));
1✔
3179
        }
3180

3181
        public Chain<String> join(final String separator) {
3182
            return new Chain<>(Underscore.join(list, separator));
1✔
3183
        }
3184

3185
        @SuppressWarnings("unchecked")
3186
        public Chain<T> push(final T... values) {
3187
            return new Chain<>(Underscore.push(value(), values));
1✔
3188
        }
3189

3190
        public Chain<Map.Entry<T, List<T>>> pop() {
3191
            return new Chain<>(Underscore.pop(value()));
1✔
3192
        }
3193

3194
        public Chain<Map.Entry<T, List<T>>> shift() {
3195
            return new Chain<>(Underscore.shift(value()));
1✔
3196
        }
3197

3198
        @SuppressWarnings("unchecked")
3199
        public Chain<T> unshift(final T... values) {
3200
            return new Chain<>(Underscore.unshift(value(), values));
1✔
3201
        }
3202

3203
        public Chain<T> skip(final int numberToSkip) {
3204
            return new Chain<>(list.subList(numberToSkip, list.size()));
1✔
3205
        }
3206

3207
        public Chain<T> limit(final int size) {
3208
            return new Chain<>(Underscore.first(list, size));
1✔
3209
        }
3210

3211
        @SuppressWarnings("unchecked")
3212
        public <K, V> Chain<Map<K, V>> toMap() {
3213
            return new Chain<>(Underscore.toMap((Iterable<Map.Entry<K, V>>) list));
1✔
3214
        }
3215

3216
        public boolean isEmpty() {
3217
            return Underscore.isEmpty(list);
1✔
3218
        }
3219

3220
        public boolean isNotEmpty() {
3221
            return Underscore.isNotEmpty(list);
1✔
3222
        }
3223

3224
        public int size() {
3225
            return Underscore.size(list);
1✔
3226
        }
3227

3228
        public T item() {
3229
            return item;
1✔
3230
        }
3231

3232
        /*
3233
         * Documented, #value
3234
         */
3235
        public List<T> value() {
3236
            return list;
1✔
3237
        }
3238

3239
        public Map<String, Object> map() {
3240
            return map;
1✔
3241
        }
3242

3243
        public List<T> toList() {
3244
            return list;
1✔
3245
        }
3246

3247
        public String toString() {
3248
            return String.valueOf(list);
1✔
3249
        }
3250
    }
3251

3252
    /*
3253
     * Documented, #mixin
3254
     */
3255
    public static void mixin(final String funcName, final UnaryOperator<String> func) {
3256
        FUNCTIONS.put(funcName, func);
1✔
3257
    }
1✔
3258

3259
    public Optional<String> call(final String funcName) {
3260
        if (string.isPresent() && FUNCTIONS.containsKey(funcName)) {
1✔
3261
            return Optional.of(FUNCTIONS.get(funcName).apply(string.get()));
1✔
3262
        }
3263
        return Optional.empty();
1✔
3264
    }
3265

3266
    public static <T extends Comparable<T>> List<T> sort(final Iterable<T> iterable) {
3267
        final List<T> localList = newArrayList(iterable);
1✔
3268
        Collections.sort(localList);
1✔
3269
        return localList;
1✔
3270
    }
3271

3272
    @SuppressWarnings("unchecked")
3273
    public static <T extends Comparable<T>> T[] sort(final T... array) {
3274
        final T[] localArray = array.clone();
1✔
3275
        Arrays.sort(localArray);
1✔
3276
        return localArray;
1✔
3277
    }
3278

3279
    @SuppressWarnings("unchecked")
3280
    public List<Comparable> sort() {
3281
        return sort((Iterable<Comparable>) iterable);
1✔
3282
    }
3283

3284
    /*
3285
     * Documented, #join
3286
     */
3287
    public static <T> String join(final Iterable<T> iterable, final String separator) {
3288
        final StringBuilder sb = new StringBuilder();
1✔
3289
        int index = 0;
1✔
3290
        for (final T item : iterable) {
1✔
3291
            if (index > 0) {
1✔
3292
                sb.append(separator);
1✔
3293
            }
3294
            sb.append(item.toString());
1✔
3295
            index += 1;
1✔
3296
        }
1✔
3297
        return sb.toString();
1✔
3298
    }
3299

3300
    public static <T> String join(final Iterable<T> iterable) {
3301
        return join(iterable, " ");
1✔
3302
    }
3303

3304
    public static <T> String join(final T[] array, final String separator) {
3305
        return join(Arrays.asList(array), separator);
1✔
3306
    }
3307

3308
    public static <T> String join(final T[] array) {
3309
        return join(array, " ");
1✔
3310
    }
3311

3312
    public String join(final String separator) {
3313
        return join(iterable, separator);
1✔
3314
    }
3315

3316
    public String join() {
3317
        return join(iterable);
1✔
3318
    }
3319

3320
    @SuppressWarnings("unchecked")
3321
    public static <T> List<T> push(final List<T> list, final T... values) {
3322
        final List<T> result = newArrayList(list);
1✔
3323
        Collections.addAll(result, values);
1✔
3324
        return result;
1✔
3325
    }
3326

3327
    @SuppressWarnings("unchecked")
3328
    public List<T> push(final T... values) {
3329
        return push((List<T>) getIterable(), values);
1✔
3330
    }
3331

3332
    public static <T> Map.Entry<T, List<T>> pop(final List<T> list) {
3333
        return Map.entry(last(list), initial(list));
1✔
3334
    }
3335

3336
    public Map.Entry<T, List<T>> pop() {
3337
        return pop((List<T>) getIterable());
1✔
3338
    }
3339

3340
    @SuppressWarnings("unchecked")
3341
    public static <T> List<T> unshift(final List<T> list, final T... values) {
3342
        final List<T> result = newArrayList(list);
1✔
3343
        int index = 0;
1✔
3344
        for (T value : values) {
1✔
3345
            result.add(index, value);
1✔
3346
            index += 1;
1✔
3347
        }
3348
        return result;
1✔
3349
    }
3350

3351
    @SuppressWarnings("unchecked")
3352
    public List<T> unshift(final T... values) {
3353
        return unshift((List<T>) getIterable(), values);
1✔
3354
    }
3355

3356
    public static <T> Map.Entry<T, List<T>> shift(final List<T> list) {
3357
        return Map.entry(first(list), rest(list));
1✔
3358
    }
3359

3360
    public Map.Entry<T, List<T>> shift() {
3361
        return shift((List<T>) getIterable());
1✔
3362
    }
3363

3364
    @SuppressWarnings("unchecked")
3365
    public static <T> T[] concat(final T[] first, final T[]... other) {
3366
        int length = 0;
1✔
3367
        for (T[] otherItem : other) {
1✔
3368
            length += otherItem.length;
1✔
3369
        }
3370
        final T[] result = Arrays.copyOf(first, first.length + length);
1✔
3371
        int index = 0;
1✔
3372
        for (T[] otherItem : other) {
1✔
3373
            System.arraycopy(otherItem, 0, result, first.length + index, otherItem.length);
1✔
3374
            index += otherItem.length;
1✔
3375
        }
3376
        return result;
1✔
3377
    }
3378

3379
    /*
3380
     * Documented, #concat
3381
     */
3382
    @SuppressWarnings("unchecked")
3383
    public static <T> List<T> concat(final Iterable<T> first, final Iterable<T>... other) {
3384
        List<T> list = newArrayList(first);
1✔
3385
        for (Iterable<T> iter : other) {
1✔
3386
            list.addAll(newArrayList(iter));
1✔
3387
        }
3388
        return list;
1✔
3389
    }
3390

3391
    @SuppressWarnings("unchecked")
3392
    public List<T> concatWith(final Iterable<T>... other) {
3393
        return concat(iterable, other);
1✔
3394
    }
3395

3396
    /*
3397
     * Documented, #slice
3398
     */
3399
    public static <T> List<T> slice(final Iterable<T> iterable, final int start) {
3400
        final List<T> result;
3401
        if (start >= 0) {
1✔
3402
            result = newArrayList(iterable).subList(start, size(iterable));
1✔
3403
        } else {
3404
            result = newArrayList(iterable).subList(size(iterable) + start, size(iterable));
1✔
3405
        }
3406
        return result;
1✔
3407
    }
3408

3409
    public static <T> T[] slice(final T[] array, final int start) {
3410
        final T[] result;
3411
        if (start >= 0) {
1✔
3412
            result = Arrays.copyOfRange(array, start, array.length);
1✔
3413
        } else {
3414
            result = Arrays.copyOfRange(array, array.length + start, array.length);
1✔
3415
        }
3416
        return result;
1✔
3417
    }
3418

3419
    public List<T> slice(final int start) {
3420
        return slice(iterable, start);
1✔
3421
    }
3422

3423
    public static <T> List<T> slice(final Iterable<T> iterable, final int start, final int end) {
3424
        final List<T> result;
3425
        if (start >= 0) {
1✔
3426
            if (end > 0) {
1✔
3427
                result = newArrayList(iterable).subList(start, end);
1✔
3428
            } else {
3429
                result = newArrayList(iterable).subList(start, size(iterable) + end);
1✔
3430
            }
3431
        } else {
3432
            if (end > 0) {
1✔
3433
                result = newArrayList(iterable).subList(size(iterable) + start, end);
1✔
3434
            } else {
3435
                result =
1✔
3436
                        newArrayList(iterable)
1✔
3437
                                .subList(size(iterable) + start, size(iterable) + end);
1✔
3438
            }
3439
        }
3440
        return result;
1✔
3441
    }
3442

3443
    public static <T> T[] slice(final T[] array, final int start, final int end) {
3444
        final T[] result;
3445
        if (start >= 0) {
1✔
3446
            if (end > 0) {
1✔
3447
                result = Arrays.copyOfRange(array, start, end);
1✔
3448
            } else {
3449
                result = Arrays.copyOfRange(array, start, array.length + end);
1✔
3450
            }
3451
        } else {
3452
            if (end > 0) {
1✔
3453
                result = Arrays.copyOfRange(array, array.length + start, end);
1✔
3454
            } else {
3455
                result = Arrays.copyOfRange(array, array.length + start, array.length + end);
1✔
3456
            }
3457
        }
3458
        return result;
1✔
3459
    }
3460

3461
    public List<T> slice(final int start, final int end) {
3462
        return slice(iterable, start, end);
1✔
3463
    }
3464

3465
    public static <T> List<List<T>> splitAt(final Iterable<T> iterable, final int position) {
3466
        List<List<T>> result = newArrayList();
1✔
3467
        int size = size(iterable);
1✔
3468
        final int index;
3469
        if (position < 0) {
1✔
3470
            index = 0;
1✔
3471
        } else {
3472
            index = position > size ? size : position;
1✔
3473
        }
3474
        result.add(newArrayList(iterable).subList(0, index));
1✔
3475
        result.add(newArrayList(iterable).subList(index, size));
1✔
3476
        return result;
1✔
3477
    }
3478

3479
    public static <T> List<List<T>> splitAt(final T[] array, final int position) {
3480
        return splitAt(Arrays.asList(array), position);
1✔
3481
    }
3482

3483
    public List<List<T>> splitAt(final int position) {
3484
        return splitAt(iterable, position);
1✔
3485
    }
3486

3487
    public static <T> List<T> takeSkipping(final Iterable<T> iterable, final int stepSize) {
3488
        List<T> result = newArrayList();
1✔
3489
        if (stepSize <= 0) {
1✔
3490
            return result;
1✔
3491
        }
3492
        int size = size(iterable);
1✔
3493
        if (stepSize > size) {
1✔
3494
            result.add(first(iterable));
1✔
3495
            return result;
1✔
3496
        }
3497
        int i = 0;
1✔
3498
        for (T element : iterable) {
1✔
3499
            if (i++ % stepSize == 0) {
1✔
3500
                result.add(element);
1✔
3501
            }
3502
        }
1✔
3503
        return result;
1✔
3504
    }
3505

3506
    public static <T> List<T> takeSkipping(final T[] array, final int stepSize) {
3507
        return takeSkipping(Arrays.asList(array), stepSize);
1✔
3508
    }
3509

3510
    public List<T> takeSkipping(final int stepSize) {
3511
        return takeSkipping(iterable, stepSize);
1✔
3512
    }
3513

3514
    /*
3515
     * Documented, #reverse
3516
     */
3517
    public static <T> List<T> reverse(final Iterable<T> iterable) {
3518
        final List<T> result = newArrayList(iterable);
1✔
3519
        Collections.reverse(result);
1✔
3520
        return result;
1✔
3521
    }
3522

3523
    @SuppressWarnings("unchecked")
3524
    public static <T> T[] reverse(final T... array) {
3525
        T temp;
3526
        final T[] newArray = array.clone();
1✔
3527
        for (int index = 0; index < array.length / 2; index += 1) {
1✔
3528
            temp = newArray[index];
1✔
3529
            newArray[index] = newArray[array.length - 1 - index];
1✔
3530
            newArray[array.length - 1 - index] = temp;
1✔
3531
        }
3532
        return newArray;
1✔
3533
    }
3534

3535
    public static List<Integer> reverse(final int[] array) {
3536
        final List<Integer> result = newIntegerList(array);
1✔
3537
        Collections.reverse(result);
1✔
3538
        return result;
1✔
3539
    }
3540

3541
    public List<T> reverse() {
3542
        return reverse(iterable);
1✔
3543
    }
3544

3545
    public Iterable<T> getIterable() {
3546
        return iterable;
1✔
3547
    }
3548

3549
    public Iterable<T> value() {
3550
        return iterable;
1✔
3551
    }
3552

3553
    public Optional<String> getString() {
3554
        return string;
1✔
3555
    }
3556

3557
    public static <T> java.util.concurrent.ScheduledFuture<T> setTimeout(
3558
            final Supplier<T> function, final int delayMilliseconds) {
3559
        return delay(function, delayMilliseconds);
1✔
3560
    }
3561

3562
    public static void clearTimeout(java.util.concurrent.ScheduledFuture<?> scheduledFuture) {
3563
        if (scheduledFuture != null) {
1✔
3564
            scheduledFuture.cancel(true);
1✔
3565
        }
3566
    }
1✔
3567

3568
    public static <T> java.util.concurrent.ScheduledFuture setInterval(
3569
            final Supplier<T> function, final int delayMilliseconds) {
3570
        final java.util.concurrent.ScheduledExecutorService scheduler =
3571
                java.util.concurrent.Executors.newSingleThreadScheduledExecutor();
1✔
3572
        return scheduler.scheduleAtFixedRate(
1✔
3573
                function::get,
1✔
3574
                delayMilliseconds,
3575
                delayMilliseconds,
3576
                java.util.concurrent.TimeUnit.MILLISECONDS);
3577
    }
3578

3579
    public static void clearInterval(java.util.concurrent.ScheduledFuture scheduledFuture) {
3580
        clearTimeout(scheduledFuture);
1✔
3581
    }
1✔
3582

3583
    public static <T> List<T> copyOf(final Iterable<T> iterable) {
3584
        return newArrayList(iterable);
1✔
3585
    }
3586

3587
    public List<T> copyOf() {
3588
        return newArrayList(value());
1✔
3589
    }
3590

3591
    public static <T> List<T> copyOfRange(
3592
            final Iterable<T> iterable, final int start, final int end) {
3593
        return slice(iterable, start, end);
1✔
3594
    }
3595

3596
    public List<T> copyOfRange(final int start, final int end) {
3597
        return slice(value(), start, end);
1✔
3598
    }
3599

3600
    public static <T> T elementAt(final List<T> list, final int index) {
3601
        return list.get(index);
1✔
3602
    }
3603

3604
    public T elementAt(final int index) {
3605
        return elementAt((List<T>) value(), index);
1✔
3606
    }
3607

3608
    public static <T> T get(final List<T> list, final int index) {
3609
        return elementAt(list, index);
1✔
3610
    }
3611

3612
    public T get(final int index) {
3613
        return elementAt((List<T>) value(), index);
1✔
3614
    }
3615

3616
    public static <T> Map.Entry<T, List<T>> set(
3617
            final List<T> list, final int index, final T value) {
3618
        final List<T> newList = newArrayList(list);
1✔
3619
        return Map.entry(newList.set(index, value), newList);
1✔
3620
    }
3621

3622
    public Map.Entry<T, List<T>> set(final int index, final T value) {
3623
        return set((List<T>) value(), index, value);
1✔
3624
    }
3625

3626
    public static <T> T elementAtOrElse(final List<T> list, final int index, T defaultValue) {
3627
        try {
3628
            return list.get(index);
1✔
3629
        } catch (IndexOutOfBoundsException ex) {
1✔
3630
            return defaultValue;
1✔
3631
        }
3632
    }
3633

3634
    public T elementAtOrElse(final int index, T defaultValue) {
3635
        return elementAtOrElse((List<T>) value(), index, defaultValue);
1✔
3636
    }
3637

3638
    public static <T> T elementAtOrNull(final List<T> list, final int index) {
3639
        try {
3640
            return list.get(index);
1✔
3641
        } catch (IndexOutOfBoundsException ex) {
1✔
3642
            return null;
1✔
3643
        }
3644
    }
3645

3646
    public T elementAtOrNull(final int index) {
3647
        return elementAtOrNull((List<T>) value(), index);
1✔
3648
    }
3649

3650
    public static <T> int lastIndex(final Iterable<T> iterable) {
3651
        return size(iterable) - 1;
1✔
3652
    }
3653

3654
    public static <T> int lastIndex(final T[] array) {
3655
        return array.length - 1;
1✔
3656
    }
3657

3658
    public static int lastIndex(final int[] array) {
3659
        return array.length - 1;
1✔
3660
    }
3661

3662
    public static <T> T checkNotNull(T reference) {
3663
        if (reference == null) {
1✔
3664
            throw new NullPointerException();
1✔
3665
        }
3666
        return reference;
1✔
3667
    }
3668

3669
    public static <T> List<T> checkNotNullElements(List<T> references) {
3670
        if (references == null) {
1✔
3671
            throw new NullPointerException();
1✔
3672
        }
3673
        for (T reference : references) {
1✔
3674
            checkNotNull(reference);
1✔
3675
        }
1✔
3676
        return references;
1✔
3677
    }
3678

3679
    public static <T> T checkNotNull(T reference, Object errorMessage) {
3680
        if (reference == null) {
1✔
3681
            throw new NullPointerException(String.valueOf(errorMessage));
1✔
3682
        }
3683
        return reference;
1✔
3684
    }
3685

3686
    public static boolean nonNull(Object obj) {
3687
        return obj != null;
1✔
3688
    }
3689

3690
    public static <T> T defaultTo(T value, T defaultValue) {
3691
        if (value == null) {
1✔
3692
            return defaultValue;
1✔
3693
        }
3694
        return value;
1✔
3695
    }
3696

3697
    protected static <T> List<T> newArrayList() {
3698
        return new ArrayList<>();
1✔
3699
    }
3700

3701
    protected static <T> List<T> newArrayList(final Iterable<T> iterable) {
3702
        final List<T> result;
3703
        if (iterable instanceof Collection) {
1✔
3704
            result = new ArrayList<>((Collection<T>) iterable);
1✔
3705
        } else {
3706
            result = new ArrayList<>();
1✔
3707
            for (final T item : iterable) {
1✔
3708
                result.add(item);
1✔
3709
            }
1✔
3710
        }
3711
        return result;
1✔
3712
    }
3713

3714
    protected static <T> List<T> newArrayList(final T object) {
3715
        final List<T> result = new ArrayList<>();
1✔
3716
        result.add(object);
1✔
3717
        return result;
1✔
3718
    }
3719

3720
    protected static <T> List<T> newArrayList(final Iterable<T> iterable, final int size) {
3721
        final List<T> result = new ArrayList<>();
1✔
3722
        for (int index = 0; iterable.iterator().hasNext() && index < size; index += 1) {
1✔
3723
            result.add(iterable.iterator().next());
1✔
3724
        }
3725
        return result;
1✔
3726
    }
3727

3728
    protected static List<Integer> newIntegerList(int... array) {
3729
        final List<Integer> result = new ArrayList<>(array.length);
1✔
3730
        for (final int item : array) {
1✔
3731
            result.add(item);
1✔
3732
        }
3733
        return result;
1✔
3734
    }
3735

3736
    protected static <T> List<T> newArrayListWithExpectedSize(int size) {
3737
        return new ArrayList<>((int) (CAPACITY_SIZE_5 + size + (size / 10)));
1✔
3738
    }
3739

3740
    protected static <T> Set<T> newLinkedHashSet() {
3741
        return new LinkedHashSet<>();
1✔
3742
    }
3743

3744
    protected static <T> Set<T> newLinkedHashSet(Iterable<T> iterable) {
3745
        final Set<T> result = new LinkedHashSet<>();
1✔
3746
        for (final T item : iterable) {
1✔
3747
            result.add(item);
1✔
3748
        }
1✔
3749
        return result;
1✔
3750
    }
3751

3752
    protected static <T> Set<T> newLinkedHashSetWithExpectedSize(int size) {
3753
        return new LinkedHashSet<>((int) Math.max(size * CAPACITY_COEFF_2, CAPACITY_SIZE_16));
1✔
3754
    }
3755

3756
    protected static <K, E> Map<K, E> newLinkedHashMap() {
3757
        return new LinkedHashMap<>();
1✔
3758
    }
3759

3760
    @SuppressWarnings("unchecked")
3761
    public static <T> Predicate<T> and(
3762
            final Predicate<? super T> pred1,
3763
            final Predicate<? super T> pred2,
3764
            final Predicate<? super T>... rest) {
3765
        checkNotNull(pred1);
1✔
3766
        checkNotNull(pred2);
1✔
3767
        checkNotNullElements(Arrays.asList(rest));
1✔
3768
        return value -> {
1✔
3769
            boolean result = pred1.test(value) && pred2.test(value);
1✔
3770
            if (!result) {
1✔
3771
                return false;
1✔
3772
            }
3773
            for (Predicate<? super T> predicate : rest) {
1✔
3774
                if (!predicate.test(value)) {
1✔
3775
                    return false;
1✔
3776
                }
3777
            }
3778
            return true;
1✔
3779
        };
3780
    }
3781

3782
    @SuppressWarnings("unchecked")
3783
    public static <T> Predicate<T> or(
3784
            final Predicate<? super T> pred1,
3785
            final Predicate<? super T> pred2,
3786
            final Predicate<? super T>... rest) {
3787
        checkNotNull(pred1);
1✔
3788
        checkNotNull(pred2);
1✔
3789
        checkNotNullElements(Arrays.asList(rest));
1✔
3790
        return value -> {
1✔
3791
            boolean result = pred1.test(value) || pred2.test(value);
1✔
3792
            if (result) {
1✔
3793
                return true;
1✔
3794
            }
3795
            for (Predicate<? super T> predicate : rest) {
1✔
3796
                if (predicate.test(value)) {
1✔
3797
                    return true;
1✔
3798
                }
3799
            }
3800
            return false;
1✔
3801
        };
3802
    }
3803

3804
    public static int minimumDays(int rows, int columns, List<List<Integer>> grid) {
3805
        Queue<int[]> queue = new LinkedList<>();
1✔
3806
        int cnt = 0;
1✔
3807
        for (int i = 0; i < rows; i++) {
1✔
3808
            for (int j = 0; j < columns; j++) {
1✔
3809
                if (grid.get(i).get(j) == 1) {
1✔
3810
                    queue.offer(new int[] {i, j});
1✔
3811
                    cnt++;
1✔
3812
                }
3813
            }
3814
        }
3815
        return getInteger(rows, columns, grid, queue, cnt);
1✔
3816
    }
3817

3818
    private static int getInteger(
3819
            int rows, int columns, List<List<Integer>> grid, Queue<int[]> queue, int cnt) {
3820
        int target = rows * columns;
1✔
3821
        int res = 0;
1✔
3822
        int localCnt = cnt;
1✔
3823
        int[][] dirs = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
1✔
3824
        while (!queue.isEmpty()) {
1✔
3825
            int size = queue.size();
1✔
3826
            if (localCnt == target) {
1✔
3827
                return res;
1✔
3828
            }
3829
            for (int i = 0; i < size; i++) {
1✔
3830
                int[] cur = queue.poll();
1✔
3831
                for (int[] dir : dirs) {
1✔
3832
                    int ni = cur[0] + dir[0];
1✔
3833
                    int nj = cur[1] + dir[1];
1✔
3834
                    if (ni >= 0
1✔
3835
                            && ni < rows
3836
                            && nj >= 0
3837
                            && nj < columns
3838
                            && grid.get(ni).get(nj) == 0) {
1✔
3839
                        localCnt++;
1✔
3840
                        queue.offer(new int[] {ni, nj});
1✔
3841
                        grid.get(ni).set(nj, 1);
1✔
3842
                    }
3843
                }
3844
            }
3845
            res++;
1✔
3846
        }
1✔
3847
        return -1;
1✔
3848
    }
3849

3850
    public static List<String> topNCompetitors(
3851
            int numCompetitors,
3852
            int topNCompetitors,
3853
            List<String> competitors,
3854
            int numReviews,
3855
            List<String> reviews) {
3856
        if (Underscore.isNull(reviews)
1✔
3857
                || reviews.isEmpty()
1✔
3858
                || Underscore.isNull(competitors)
1✔
3859
                || competitors.isEmpty()
1✔
3860
                || numReviews < 1
3861
                || numCompetitors < 1) {
3862
            return new ArrayList<>();
1✔
3863
        }
3864

3865
        List<String> topNCompetitorsList = new ArrayList<>(topNCompetitors);
1✔
3866

3867
        Set<String> competitorsSet = new HashSet<>(competitors);
1✔
3868
        Map<String, Integer> topCompetitorsMap = new HashMap<>();
1✔
3869
        List<Map.Entry<String, Integer>> list =
1✔
3870
                getEntries(reviews, competitorsSet, topCompetitorsMap);
1✔
3871

3872
        for (Map.Entry<String, Integer> item : list) {
1✔
3873
            if (topNCompetitorsList.size() < topNCompetitors) {
1✔
3874
                topNCompetitorsList.add(item.getKey());
1✔
3875
            } else {
3876
                break;
3877
            }
3878
        }
1✔
3879

3880
        return topNCompetitorsList;
1✔
3881
    }
3882

3883
    private static List<Map.Entry<String, Integer>> getEntries(
3884
            List<String> reviews,
3885
            Set<String> competitorsSet,
3886
            Map<String, Integer> topCompetitorsMap) {
3887
        // clean the reviews first: lowercase, remove special characters and split by spaces.
3888
        for (String review : reviews) {
1✔
3889
            String[] reviewArray = review.toLowerCase().replaceAll("[^a-zA-Z0-9 ]", "").split(" ");
1✔
3890
            Set<String> tempCompetitorSet = new HashSet<>();
1✔
3891

3892
            for (String text : reviewArray) {
1✔
3893
                if (competitorsSet.contains(text) && !tempCompetitorSet.contains(text)) {
1✔
3894
                    tempCompetitorSet.add(text);
1✔
3895
                    if (topCompetitorsMap.containsKey(text)) {
1✔
3896
                        topCompetitorsMap.put(text, topCompetitorsMap.get(text) + 1);
1✔
3897
                    } else {
3898
                        topCompetitorsMap.put(text, 1);
1✔
3899
                    }
3900
                }
3901
            }
3902
        }
1✔
3903

3904
        return getEntries(topCompetitorsMap);
1✔
3905
    }
3906

3907
    private static List<Map.Entry<String, Integer>> getEntries(
3908
            Map<String, Integer> topCompetitorsMap) {
3909
        List<Map.Entry<String, Integer>> list = new ArrayList<>(topCompetitorsMap.entrySet());
1✔
3910
        list.sort(new ValueThenKeyComparator<>());
1✔
3911
        return list;
1✔
3912
    }
3913

3914
    public static class ValueThenKeyComparator<
1✔
3915
                    K extends Comparable<? super K>, V extends Comparable<? super V>>
3916
            implements Comparator<Map.Entry<K, V>>, java.io.Serializable {
3917

3918
        public int compare(Map.Entry<K, V> a, Map.Entry<K, V> b) {
3919
            int cmp1 = b.getValue().compareTo(a.getValue());
1✔
3920
            if (cmp1 == 0) {
1✔
3921
                return a.getKey().compareTo(b.getKey());
1✔
3922
            }
3923
            return cmp1;
1✔
3924
        }
3925
    }
3926

3927
    public static void main(String... args) {
3928
        final String message =
1✔
3929
                "Underscore-java is a java port of Underscore.js.\n\n"
3930
                        + "In addition to porting Underscore's functionality,"
3931
                        + " Underscore-java includes matching unit tests.\n\n"
3932
                        + "For docs, license, tests, and downloads, see: https://javadev.github.io/underscore-java";
3933
        System.out.println(message);
1✔
3934
    }
1✔
3935
}
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