1010import java .util .LinkedHashMap ;
1111import java .util .List ;
1212import java .util .Map ;
13+ import java .util .NoSuchElementException ;
1314import java .util .Optional ;
15+ import java .util .OptionalInt ;
1416import java .util .concurrent .CompletableFuture ;
1517import java .util .function .BiFunction ;
1618import java .util .function .BinaryOperator ;
1921import java .util .function .Supplier ;
2022import java .util .stream .Collectors ;
2123import java .util .stream .IntStream ;
24+ import java .util .stream .Stream ;
2225
2326import static java .util .Collections .singletonList ;
2427import static java .util .function .Function .identity ;
@@ -31,10 +34,10 @@ public class FpKit {
3134 // From a list of named things, get a map of them by name, merging them according to the merge function
3235 public static <T > Map <String , T > getByName (List <T > namedObjects , Function <T , String > nameFn , BinaryOperator <T > mergeFunc ) {
3336 return namedObjects .stream ().collect (Collectors .toMap (
34- nameFn ,
35- identity (),
36- mergeFunc ,
37- LinkedHashMap ::new )
37+ nameFn ,
38+ identity (),
39+ mergeFunc ,
40+ LinkedHashMap ::new )
3841 );
3942 }
4043
@@ -45,10 +48,10 @@ public static <T, NewKey> Map<NewKey, List<T>> groupingBy(Collection<T> list, Fu
4548
4649 public static <T , NewKey > Map <NewKey , T > groupingByUniqueKey (Collection <T > list , Function <T , NewKey > keyFunction ) {
4750 return list .stream ().collect (Collectors .toMap (
48- keyFunction ,
49- identity (),
50- throwingMerger (),
51- LinkedHashMap ::new )
51+ keyFunction ,
52+ identity (),
53+ throwingMerger (),
54+ LinkedHashMap ::new )
5255 );
5356 }
5457
@@ -75,17 +78,15 @@ public static <T> BinaryOperator<T> mergeFirst() {
7578 *
7679 * @param iterableResult the result object
7780 * @param <T> the type of thing
78- *
7981 * @return an Iterable from that object
80- *
8182 * @throws java.lang.ClassCastException if its not an Iterable
8283 */
8384 @ SuppressWarnings ("unchecked" )
8485 public static <T > Collection <T > toCollection (Object iterableResult ) {
8586 if (iterableResult .getClass ().isArray ()) {
8687 List <Object > collect = IntStream .range (0 , Array .getLength (iterableResult ))
87- .mapToObj (i -> Array .get (iterableResult , i ))
88- .collect (Collectors .toList ());
88+ .mapToObj (i -> Array .get (iterableResult , i ))
89+ .collect (Collectors .toList ());
8990 return (List <T >) collect ;
9091 }
9192 if (iterableResult instanceof Collection ) {
@@ -100,14 +101,79 @@ public static <T> Collection<T> toCollection(Object iterableResult) {
100101 return list ;
101102 }
102103
104+ public static boolean isIterable (Object result ) {
105+ return result .getClass ().isArray () || result instanceof Iterable || result instanceof Stream || result instanceof Iterator ;
106+ }
107+
108+
109+ @ SuppressWarnings ("unchecked" )
110+ public static <T > Iterable <T > toIterable (Object iterableResult ) {
111+ if (iterableResult instanceof Iterable ) {
112+ return ((Iterable <T >) iterableResult );
113+ }
114+
115+ if (iterableResult instanceof Stream ) {
116+ return ((Stream <T >) iterableResult )::iterator ;
117+ }
118+
119+ if (iterableResult instanceof Iterator ) {
120+ return () -> (Iterator <T >) iterableResult ;
121+ }
122+
123+ if (iterableResult .getClass ().isArray ()) {
124+ return () -> new ArrayIterator <>(iterableResult );
125+ }
126+
127+ throw new ClassCastException ("not Iterable: " + iterableResult .getClass ());
128+ }
129+
130+ private static class ArrayIterator <T > implements Iterator <T > {
131+
132+ private final Object array ;
133+ private final int size ;
134+ private int i ;
135+
136+ private ArrayIterator (Object array ) {
137+ this .array = array ;
138+ this .size = Array .getLength (array );
139+ this .i = 0 ;
140+ }
141+
142+ @ Override
143+ public boolean hasNext () {
144+ return i < size ;
145+ }
146+
147+ @ SuppressWarnings ("unchecked" )
148+ @ Override
149+ public T next () {
150+ if (!hasNext ()) {
151+ throw new NoSuchElementException ();
152+ }
153+ return (T ) Array .get (array , i ++);
154+ }
155+
156+ }
157+
158+ public static OptionalInt toSize (Object iterableResult ) {
159+ if (iterableResult instanceof Collection ) {
160+ return OptionalInt .of (((Collection <?>) iterableResult ).size ());
161+ }
162+
163+ if (iterableResult .getClass ().isArray ()) {
164+ return OptionalInt .of (Array .getLength (iterableResult ));
165+ }
166+
167+ return OptionalInt .empty ();
168+ }
169+
103170 /**
104171 * Concatenates (appends) a single elements to an existing list
105172 *
106173 * @param l the list onto which to append the element
107174 * @param t the element to append
108175 * @param <T> the type of elements of the list
109- *
110- * @return a <strong>new</strong> list componsed of the first list elements and the new element
176+ * @return a <strong>new</strong> list composed of the first list elements and the new element
111177 */
112178 public static <T > List <T > concat (List <T > l , T t ) {
113179 return concat (l , singletonList (t ));
@@ -119,7 +185,6 @@ public static <T> List<T> concat(List<T> l, T t) {
119185 * @param l1 the first list to concatenate
120186 * @param l2 the second list to concatenate
121187 * @param <T> the type of element of the lists
122- *
123188 * @return a <strong>new</strong> list composed of the two concatenated lists elements
124189 */
125190 public static <T > List <T > concat (List <T > l1 , List <T > l2 ) {
@@ -152,7 +217,7 @@ public static <T> List<List<T>> transposeMatrix(List<? extends List<T>> matrix)
152217 for (int j = 0 ; j < colCount ; j ++) {
153218 T val = matrix .get (i ).get (j );
154219 if (result .size () <= j ) {
155- result .add (j , new ArrayList ());
220+ result .add (j , new ArrayList <> ());
156221 }
157222 result .get (j ).add (i , val );
158223 }
@@ -166,15 +231,15 @@ public static <T> CompletableFuture<List<T>> flatList(CompletableFuture<List<Lis
166231
167232 public static <T > List <T > flatList (List <List <T >> listLists ) {
168233 return listLists .stream ()
169- .flatMap (List ::stream )
170- .collect (Collectors .toList ());
234+ .flatMap (List ::stream )
235+ .collect (Collectors .toList ());
171236 }
172237
173238 public static <T > Optional <T > findOne (Collection <T > list , Predicate <T > filter ) {
174239 return list
175- .stream ()
176- .filter (filter )
177- .findFirst ();
240+ .stream ()
241+ .filter (filter )
242+ .findFirst ();
178243 }
179244
180245 public static <T > T findOneOrNull (List <T > list , Predicate <T > filter ) {
0 commit comments