1 | package com.renomad.minum.utils; | |
2 | ||
3 | import java.util.List; | |
4 | import java.util.Objects; | |
5 | import java.util.concurrent.Callable; | |
6 | import java.util.function.Predicate; | |
7 | import java.util.stream.Stream; | |
8 | ||
9 | import static com.renomad.minum.utils.Invariants.mustBeTrue; | |
10 | ||
11 | /** | |
12 | * Utilities for searching collections of data | |
13 | */ | |
14 | public final class SearchUtils { | |
15 | ||
16 | private SearchUtils() { | |
17 | // not meant to be instantiated | |
18 | } | |
19 | ||
20 | /** | |
21 | * This helper method will give you the one item in this list, or | |
22 | * null if there are none. If there's more than 1, it will throw | |
23 | * an exception. This is for those times when we absolutely expect | |
24 | * there to be just one of a thing in a database, like if we're searching | |
25 | * for Persons by id. | |
26 | * @param searchPredicate a {@link Predicate} run to search for an element in the stream. | |
27 | * @throws InvariantException if there are two or more results found | |
28 | */ | |
29 | public static <T> T findExactlyOne(Stream<T> streamOfSomething, Predicate<? super T> searchPredicate) { | |
30 |
1
1. findExactlyOne : replaced return value with null for com/renomad/minum/utils/SearchUtils::findExactlyOne → KILLED |
return findExactlyOne(streamOfSomething, searchPredicate, () -> null); |
31 | } | |
32 | ||
33 | /** | |
34 | * This is similar to {@link #findExactlyOne(Stream, Predicate)} except that you | |
35 | * can provide what gets returned if there are none found - so instead of | |
36 | * returning null, it can return something else. | |
37 | * <br> | |
38 | * The values will be pre-filtered to skip any null values. | |
39 | * <br> | |
40 | * @param alternate a {@link Callable} that will be run when no elements were found. | |
41 | * @param searchPredicate a {@link Predicate} run to search for an element in the stream. | |
42 | * @throws InvariantException if there are two or more results found | |
43 | */ | |
44 | public static <T> T findExactlyOne(Stream<T> streamOfSomething, Predicate<? super T> searchPredicate, Callable<T> alternate) { | |
45 | List<T> listOfThings = streamOfSomething.filter(Objects::nonNull).filter(searchPredicate).toList(); | |
46 | mustBeTrue(listOfThings.isEmpty() || listOfThings.size() == 1, "Must be zero or one of this thing, or it's a bug. We found a size of " + listOfThings.size()); | |
47 |
1
1. findExactlyOne : negated conditional → KILLED |
if (listOfThings.isEmpty()) { |
48 | T returnValue; | |
49 | try { | |
50 | returnValue = alternate.call(); | |
51 | } catch (Exception ex) { | |
52 | throw new UtilsException(ex); | |
53 | } | |
54 |
1
1. findExactlyOne : replaced return value with null for com/renomad/minum/utils/SearchUtils::findExactlyOne → KILLED |
return returnValue; |
55 | } else { | |
56 |
1
1. findExactlyOne : replaced return value with null for com/renomad/minum/utils/SearchUtils::findExactlyOne → KILLED |
return listOfThings.getFirst(); |
57 | } | |
58 | } | |
59 | } | |
Mutations | ||
30 |
1.1 |
|
47 |
1.1 |
|
54 |
1.1 |
|
56 |
1.1 |