/* * This is free and unencumbered software released into the public domain. * * Anyone is free to copy, modify, publish, use, compile, sell, or * distribute this software, either in source code form or as a compiled * binary, for any purpose, commercial or non-commercial, and by any * means. * * In jurisdictions that recognize copyright laws, the author or authors * of this software dedicate any and all copyright interest in the * software to the public domain. We make this dedication for the benefit * of the public at large and to the detriment of our heirs and * successors. We intend this dedication to be an overt act of * relinquishment in perpetuity of all present and future rights to this * software under copyright law. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * For more information, please refer to <http://unlicense.org/> */ package java.lang; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; import java.util.Objects; import java.util.TreeMap; import java.util.TreeSet; import java.util.function.BiFunctionEx; import java.util.function.ConsumerEx; import java.util.function.Function; import java.util.function.FunctionEx; import java.util.function.Predicate; import java.util.function.PredicateEx; import java.util.function.ToDoubleFunctionEx; import java.util.function.ToIntFunctionEx; import java.util.function.ToLongFunctionEx; import jxtn.core.axi.collections.AfterConditionIterator; import jxtn.core.axi.collections.BeforeConditionIterator; import jxtn.core.axi.collections.ConcatedIterator; import jxtn.core.axi.collections.ExpandedIterator; import jxtn.core.axi.collections.FilteredIterator; import jxtn.core.axi.collections.IndexedItem; import jxtn.core.axi.collections.IndexedIterator; import jxtn.core.axi.collections.LinkLineIterator; import jxtn.core.axi.collections.LinkTreeIterator; import jxtn.core.axi.collections.MappedIterator; import jxtn.core.axi.collections.SkippedIterator; /** * Extension to {@link Iterable} * <p> * Extension methods here are synchronized with those in {@link java.util.IteratorExt} * </p> * * @author AqD * @param <T> The {@link Iterable} element type */ public interface IterableExt<T> { /** * Combine multiple {@link Iterable} into a single {@link Iterable} * * @param <T> The {@link Iterable} element type * @param iterables Iterables of the same element type to combine * @return The combined {@link Iterable} which can be used to iterate through all items from {@code iterables} */ @SafeVarargs static <T> Iterable<T> concatAll(Iterable<? extends T>... iterables) { return () -> new ConcatedIterator<>(Arrays.asList(iterables).iterator().mapRemaining(Iterable::iterator)); } /** * Combine multiple {@link Iterable} into a single {@link Iterable} which can then iterate through all items * * @param <T> The {@link Iterable} element type * @param iterableIterable Iterable of iterables of the same element type to combine * @return The combined {@link Iterable} which can be used to iterate through all items from {@code iterables} */ static <T> Iterable<T> concatAll(Iterable<Iterable<? extends T>> iterableIterable) { return () -> new ConcatedIterator<>(iterableIterable.iterator().mapRemaining(Iterable::iterator)); } /** * Combine multiple {@link Iterable} into a single {@link Iterable} which can then iterate through all items * * @param <T> The {@link Iterable} element type * @param iterableIterator Iterator of iterables of the same element type to combine * @return The combined {@link Iterable} which can be used to iterate through all items from {@code iterables} */ static <T> Iterable<T> concatAll(Iterator<Iterable<? extends T>> iterableIterator) { return () -> new ConcatedIterator<>(iterableIterator.mapRemaining(Iterable::iterator)); } /** * Link a line structure into an {@link Iterable} of elements * * @param <T> {@link Iterable} element type * @param item The initial item (head) * @param getNext A function to get the next item from the given item or return null at the end * @return The {@link Iterable} of elements representing this line structure, starting from {@code item} */ static <T> Iterable<T> linkLine(T item, Function<? super T, ? extends T> getNext) { return () -> new LinkLineIterator<>(item, getNext); } /** * Link a tree structure into an {@link Iterable} of elements (depth-first search) * * @param <T> The {@link Iterable} element type * @param item The initial item (root node) * @param getChildren The function to get child nodes of the given node or return null at the end * @return The {@link Iterable} of elements representing this tree structure, starting from {@code item} as root * node (depth-first search) */ static <T> Iterable<T> linkTree(T item, Function<? super T, ? extends Iterable<? extends T>> getChildren) { return () -> new LinkTreeIterator<>(item, t -> { Iterable<? extends T> children = getChildren.apply(t); return children == null ? null : children.iterator(); }); } /** * Performs the given action for each element of this {@link Iterable} while allowing {@code TException} to happen * * @param <TException> The type of exception allowed to be thrown from {@code action} * @param action The action to be performed for each element * @throws TException The first exception from {@code action} */ default <TException extends Exception> void forEachEx(ConsumerEx<? super T, ? extends TException> action) throws TException { Objects.requireNonNull(action); Iterable<T> thiz = (Iterable<T>) this; for (T item : thiz) { action.acceptEx(item); } } ////////////////////////////////////////////////////////////////////////// // 條件測試 // /** * Check whether all elements of this {@link Iterable} match the given condition * * @param <TException> The type of exception allowed to be thrown from {@code condition} * @param condition The condition to test elements in this {@link Iterable} * @return true if all elements match {@code condition} or the {@link Iterable} contains no element * @throws TException The first exception from {@code condition} */ default <TException extends Exception> boolean all(PredicateEx<? super T, ? extends TException> condition) throws TException { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().allRemaining(condition); } /** * Check if any of the elements in this {@link Iterable} matches the given condition * * @param <TException> The type of exception allowed to be thrown from {@code condition} * @param condition The condition to test elements in this {@link Iterable} * @return true if at least one element matches {@code condition} * @throws TException The first exception from {@code condition} */ default <TException extends Exception> boolean any(PredicateEx<? super T, ? extends TException> condition) throws TException { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().anyRemaining(condition); } ////////////////////////////////////////////////////////////////////////// // 列舉轉換 // /** * Return the current {@link Iterable} as an {@link Iterable} of a different element type {@code V} (unchecked * conversion) * * @param <V> The target element type * @return The current {@link Iterable} as an {@link Iterable} of {@code V} (unchecked conversion) */ @SuppressWarnings("unchecked") default <V> Iterable<V> as() { return (Iterable<V>) this; } /** * Construct a new {@link Iterable} from the current one with new items appended to the end * * @param tailItems Items to be appended to the end * @return a new {@link Iterable} from the current one with {@code tailItems} appended to the end */ @SuppressWarnings("unchecked") default Iterable<T> append(T... tailItems) { List<Iterable<? extends T>> list = Arrays.asList( (Iterable<T>) this, Arrays.asList(tailItems)); return () -> new ConcatedIterator<>(list.iterator().mapRemaining(Iterable::iterator)); } /** * Construct a new {@link Iterable} from the current one with new items appended to the beginning * * @param headItems Items to be inserted to the beginning * @return a new {@link Iterable} from the current one with {@code headItems} inserted to the beginning */ @SuppressWarnings("unchecked") default Iterable<T> prepend(T... headItems) { List<Iterable<? extends T>> list = Arrays.asList( Arrays.asList(headItems), (Iterable<T>) this); return () -> new ConcatedIterator<>(list.iterator().mapRemaining(Iterable::iterator)); } /** * Construct a new {@link Iterable} from the current one with given {@link Iterable} of items appended to the end * * @param iterables {@link Iterable} of items to be appended to the end * @return A new {@link Iterable} from the current one with given {@link Iterable} of items appended to the end */ @SuppressWarnings("unchecked") default Iterable<T> concat(Iterable<? extends T>... iterables) { List<Iterable<? extends T>> list = new ArrayList<>(iterables.length + 1); list.add((Iterable<T>) this); for (Iterable<? extends T> other : iterables) { list.add(other); } return () -> new ConcatedIterator<>(list.iterator().mapRemaining(Iterable::iterator)); } /** * Construct a new {@link Iterable} with each of element in this {@link Iterable} expanded into one or multiple * elements of another type by a specified expansion function * * @param <R> The element type after expansion * @param expander A function to expand each element into multiple elements of {@code R} * @return A new {@link Iterable} with each of element in this {@link Iterable} expanded by {@code expander} */ default <R> Iterable<R> expand(Function<? super T, ? extends Iterable<? extends R>> expander) { Iterable<T> thiz = (Iterable<T>) this; return () -> new ExpandedIterator<>(thiz.iterator(), t -> expander.apply(t).iterator()); } /** * Construct a new {@link Iterable} with each of element in this {@link Iterable} expanded into one or multiple * elements of another type by a specified expansion function * * @param <R> The element type after expansion * @param expander A function to expand each element into multiple elements of {@code R} * @return A new {@link Iterable} with each of element in this {@link Iterable} expanded by {@code expander} */ @SuppressWarnings("deprecation") default <R> Iterable<R> expandEx(FunctionEx<? super T, ? extends Iterable<? extends R>, Exception> expander) { Iterable<T> thiz = (Iterable<T>) this; return () -> new ExpandedIterator<>(thiz.iterator(), t -> expander.apply(t).iterator()); } /** * 依照條件建立過濾列舉(保留符合條件之項目)。 * * @param condition 過濾條件 * @return 過濾列舉,依賴原有的列舉 */ default Iterable<T> filter(Predicate<? super T> condition) { Iterable<T> thiz = (Iterable<T>) this; return () -> new FilteredIterator<>(thiz.iterator(), condition); } /** * 依照條件建立過濾列舉(保留符合條件之項目)。 * * @param condition 過濾條件 * @return 過濾列舉,依賴原有的列舉 */ default Iterable<T> filterEx(PredicateEx<? super T, Exception> condition) { Iterable<T> thiz = (Iterable<T>) this; return () -> new FilteredIterator<>(thiz.iterator(), condition); } /** * 依照條件建立剔除開頭的過濾列舉(保留符合條件之後項目,包含該項)。 * * @param condition 過濾條件 * @return 過濾列舉,依賴原有的列舉 */ default Iterable<T> after(Predicate<? super T> condition) { Iterable<T> thiz = (Iterable<T>) this; return () -> new AfterConditionIterator<>(thiz.iterator(), condition); } /** * 依照條件建立剔除開頭的過濾列舉(保留符合條件之後項目,包含該項)。 * * @param condition 過濾條件 * @return 過濾列舉,依賴原有的列舉 */ default Iterable<T> afterEx(PredicateEx<? super T, Exception> condition) { Iterable<T> thiz = (Iterable<T>) this; return () -> new AfterConditionIterator<>(thiz.iterator(), condition); } /** * 依照條件建立剔除結尾的過濾列舉(保留符合條件之前項目,不含該項)。 * * @param condition 過濾條件 * @return 過濾列舉,依賴原有的列舉 */ default Iterable<T> before(Predicate<? super T> condition) { Iterable<T> thiz = (Iterable<T>) this; return () -> new BeforeConditionIterator<>(thiz.iterator(), condition); } /** * 依照條件建立剔除結尾的過濾列舉(保留符合條件之前項目,不含該項)。 * * @param condition 過濾條件 * @return 過濾列舉,依賴原有的列舉 */ default Iterable<T> beforeEx(PredicateEx<? super T, Exception> condition) { Iterable<T> thiz = (Iterable<T>) this; return () -> new BeforeConditionIterator<>(thiz.iterator(), condition); } /** * 建立加上索引的列舉。 * * @return 加上索引的列舉,依賴原有的列舉 */ default Iterable<IndexedItem<T>> indexed() { Iterable<T> thiz = (Iterable<T>) this; return () -> new IndexedIterator<>(thiz.iterator()); } /** * 依照對照函數建立對照列舉。 * * @param <R> 對照項目型態 * @param mapper 對照項目的函數 * @return 對照列舉,依賴原有的列舉 */ default <R> Iterable<R> map(Function<? super T, ? extends R> mapper) { Iterable<T> thiz = (Iterable<T>) this; return () -> new MappedIterator<>(thiz.iterator(), mapper); } /** * 依照對照函數建立對照列舉。 * * @param <R> 對照項目型態 * @param mapper 對照項目的函數 * @return 對照列舉,依賴原有的列舉 */ default <R> Iterable<R> mapEx(FunctionEx<? super T, ? extends R, Exception> mapper) { Iterable<T> thiz = (Iterable<T>) this; return () -> new MappedIterator<>(thiz.iterator(), mapper); } /** * 建立只包含指定型態項目的列舉。 * * @param <R> 要取得項目的型態 * @param type 要取得項目的型態 * @return 只包含{@code type}型態項目的列舉 */ @SuppressWarnings("unchecked") default <R> Iterable<R> ofType(Class<? extends R> type) { return this.filter(type::isInstance).map(t -> (R) t); } /** * 建立跳過指定項目數量的列舉。 * * @param count 要跳過的項目數量 * @return 跳過指定數量的列舉,依賴原有的列舉 */ default Iterable<T> skip(int count) { Iterable<T> thiz = (Iterable<T>) this; return () -> new SkippedIterator<>(thiz.iterator(), count); } ////////////////////////////////////////////////////////////////////////// // 項目挑選 // /** * 取得第一筆項目。 * * @return 第一筆項目 * @throws NoSuchElementException 沒有任何項目 */ default T first() { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().next(); } /** * 取得符合條件的第一筆項目。 * * @param <TException> 測試條件可拋出的例外型態 * @param condition 取得項目的條件測試函數 * @return 符合條件的第一筆項目 * @throws NoSuchElementException 沒有任何符合條件的項目 * @throws TException 表示{@code condition}丟出例外 */ default <TException extends Exception> T first(PredicateEx<? super T, ? extends TException> condition) throws TException { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().next(condition); } /** * 取得第一筆項目或null。 * * @return 第一筆項目,或null表示沒有項目 */ default T firstOrNull() { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().nextOrNull(); } /** * 取得符合條件的第一筆項目或null。 * * @param <TException> 測試條件可拋出的例外型態 * @param condition 取得項目的條件測試函數 * @return 符合條件的第一筆項目,或null表示沒有項目 * @throws TException 表示{@code condition}丟出例外 */ default <TException extends Exception> T firstOrNull(PredicateEx<? super T, ? extends TException> condition) throws TException { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().nextOrNull(condition); } /** * 取得第一個可計算出最大數值的項目。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param <V> 數值型態 * @param getValue 計算項目數值的函數 * @return 第一個計算出最大數值的項目 * @throws NoSuchElementException 沒有項目 * @throws TException 表示{@code getValue}丟出例外 */ default <V extends Comparable<? super V>, TException extends Exception> T firstOfMax( FunctionEx<? super T, ? extends V, ? extends TException> getValue) throws TException { Iterable<T> thiz = (Iterable<T>) this; Iterator<T> it = thiz.iterator(); return it.nextOfMax(getValue); } /** * 取得第一個可計算出最大數值的項目。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param <V> 數值型態 * @param getValue 計算項目數值的函數 * @return 第一個計算出最大數值的項目,或null表示沒有項目 * @throws TException 表示{@code getValue}丟出例外 */ default <V extends Comparable<? super V>, TException extends Exception> T firstOfMaxOrNull( FunctionEx<? super T, ? extends V, ? extends TException> getValue) throws TException { Iterable<T> thiz = (Iterable<T>) this; Iterator<T> it = thiz.iterator(); return it.hasNext() ? it.nextOfMax(getValue) : null; } /** * 取得第一個可計算出最大數值的項目。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 第一個計算出最大數值的項目 * @throws NoSuchElementException 沒有項目 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> T firstOfMaxDouble( ToDoubleFunctionEx<? super T, ? extends TException> getValue) throws TException { Iterable<T> thiz = (Iterable<T>) this; Iterator<T> it = thiz.iterator(); return it.nextOfMaxDouble(getValue); } /** * 取得第一個可計算出最大數值的項目。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 第一個計算出最大數值的項目,或null表示沒有項目 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> T firstOfMaxDoubleOrNull( ToDoubleFunctionEx<? super T, ? extends TException> getValue) throws TException { Iterable<T> thiz = (Iterable<T>) this; Iterator<T> it = thiz.iterator(); return it.hasNext() ? it.nextOfMaxDouble(getValue) : null; } /** * 取得第一個可計算出最大數值的項目。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 第一個計算出最大數值的項目 * @throws NoSuchElementException 沒有項目 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> T firstOfMaxInt(ToIntFunctionEx<? super T, ? extends TException> getValue) throws TException { Iterable<T> thiz = (Iterable<T>) this; Iterator<T> it = thiz.iterator(); return it.nextOfMaxInt(getValue); } /** * 取得第一個可計算出最大數值的項目。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 第一個計算出最大數值的項目,或null表示沒有項目 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> T firstOfMaxIntOrNull( ToIntFunctionEx<? super T, ? extends TException> getValue) throws TException { Iterable<T> thiz = (Iterable<T>) this; Iterator<T> it = thiz.iterator(); return it.hasNext() ? it.nextOfMaxInt(getValue) : null; } /** * 取得第一個可計算出最大數值的項目。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 第一個計算出最大數值的項目 * @throws NoSuchElementException 沒有項目 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> T firstOfMaxLong(ToLongFunctionEx<? super T, ? extends TException> getValue) throws TException { Iterable<T> thiz = (Iterable<T>) this; Iterator<T> it = thiz.iterator(); return it.nextOfMaxLong(getValue); } /** * 取得第一個可計算出最大數值的項目。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 第一個計算出最大數值的項目,或null表示沒有項目 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> T firstOfMaxLongOrNull( ToLongFunctionEx<? super T, ? extends TException> getValue) throws TException { Iterable<T> thiz = (Iterable<T>) this; Iterator<T> it = thiz.iterator(); return it.hasNext() ? it.nextOfMaxLong(getValue) : null; } /** * 取得第一個可計算出最小數值的項目。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param <V> 數值型態 * @param getValue 計算項目數值的函數 * @return 第一個計算出最小數值的項目 * @throws NoSuchElementException 沒有項目 * @throws TException 表示{@code getValue}丟出例外 */ default <V extends Comparable<? super V>, TException extends Exception> T firstOfMin( FunctionEx<? super T, ? extends V, ? extends TException> getValue) throws TException { Iterable<T> thiz = (Iterable<T>) this; Iterator<T> it = thiz.iterator(); return it.nextOfMin(getValue); } /** * 取得第一個可計算出最小數值的項目。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param <V> 數值型態 * @param getValue 計算項目數值的函數 * @return 第一個計算出最小數值的項目,或null表示沒有項目 * @throws TException 表示{@code getValue}丟出例外 */ default <V extends Comparable<? super V>, TException extends Exception> T firstOfMinOrNull( FunctionEx<? super T, ? extends V, ? extends TException> getValue) throws TException { Iterable<T> thiz = (Iterable<T>) this; Iterator<T> it = thiz.iterator(); return it.hasNext() ? it.nextOfMin(getValue) : null; } /** * 取得第一個可計算出最小數值的項目。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 第一個計算出最小數值的項目 * @throws NoSuchElementException 沒有項目 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> T firstOfMinDouble( ToDoubleFunctionEx<? super T, ? extends TException> getValue) throws TException { Iterable<T> thiz = (Iterable<T>) this; Iterator<T> it = thiz.iterator(); return it.nextOfMinDouble(getValue); } /** * 取得第一個可計算出最小數值的項目。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 第一個計算出最小數值的項目,或null表示沒有項目 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> T firstOfMinDoubleOrNull( ToDoubleFunctionEx<? super T, ? extends TException> getValue) throws TException { Iterable<T> thiz = (Iterable<T>) this; Iterator<T> it = thiz.iterator(); return it.hasNext() ? it.nextOfMinDouble(getValue) : null; } /** * 取得第一個可計算出最小數值的項目。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 第一個計算出最小數值的項目 * @throws NoSuchElementException 沒有項目 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> T firstOfMinInt(ToIntFunctionEx<? super T, ? extends TException> getValue) throws TException { Iterable<T> thiz = (Iterable<T>) this; Iterator<T> it = thiz.iterator(); return it.nextOfMinInt(getValue); } /** * 取得第一個可計算出最小數值的項目。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 第一個計算出最小數值的項目,或null表示沒有項目 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> T firstOfMinIntOrNull( ToIntFunctionEx<? super T, ? extends TException> getValue) throws TException { Iterable<T> thiz = (Iterable<T>) this; Iterator<T> it = thiz.iterator(); return it.hasNext() ? it.nextOfMinInt(getValue) : null; } /** * 取得第一個可計算出最小數值的項目。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 第一個計算出最小數值的項目 * @throws NoSuchElementException 沒有項目 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> T firstOfMinLong(ToLongFunctionEx<? super T, ? extends TException> getValue) throws TException { Iterable<T> thiz = (Iterable<T>) this; Iterator<T> it = thiz.iterator(); return it.nextOfMinLong(getValue); } /** * 取得第一個可計算出最小數值的項目。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 第一個計算出最小數值的項目,或null表示沒有項目 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> T firstOfMinLongOrNull( ToLongFunctionEx<? super T, ? extends TException> getValue) throws TException { Iterable<T> thiz = (Iterable<T>) this; Iterator<T> it = thiz.iterator(); return it.hasNext() ? it.nextOfMinLong(getValue) : null; } /** * 取得第N筆項目。 * * @param position 位置 * @return 第N筆項目 * @throws NoSuchElementException 沒有第N筆項目 */ default T getNth(int position) { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().nextNth(position); } /** * 取得第N筆項目。 * * @param position 位置 * @return 第N筆項目,或null表示沒有第N筆項目 */ default T getNthOrNull(int position) { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().nextNthOrNull(position); } /** * 取得最後一筆項目。 * * @return 最後一筆項目 * @throws NoSuchElementException 沒有任何項目 */ default T last() { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().lastOfRemaining(); } /** * 取得符合條件的最後一筆項目。 * * @param <TException> 測試條件可拋出的例外型態 * @param condition 取得項目的條件測試函數 * @return 最後一筆項目 * @throws NoSuchElementException 沒有最後一筆或符合條件的項目 * @throws TException 表示{@code condition}丟出例外 */ default <TException extends Exception> T last(PredicateEx<? super T, ? extends TException> condition) throws TException { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().lastOfRemaining(condition); } /** * 取得最後一筆項目或null。 * * @return 最後一筆項目,或null表示沒有項目 */ default T lastOrNull() { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().lastOfRemainingOrNull(); } /** * 取得符合條件的最後一筆項目或null。 * * @param <TException> 測試條件可拋出的例外型態 * @param condition 取得項目的條件測試函數 * @return 最後一筆項目,或null表示沒有符合條件的項目 * @throws TException 表示{@code condition}丟出例外 */ default <TException extends Exception> T lastOrNull(PredicateEx<? super T, ? extends TException> condition) throws TException { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().lastOfRemainingOrNull(condition); } ////////////////////////////////////////////////////////////////////////// // 項目統整 // /** * 用目前項目值建立陣列。 * * @param type 陣列項目型態 * @return 包含目前項目的陣列 */ default T[] toArray(Class<T> type) { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().remainingToArray(type); } /** * 用目前項目值建立{@link ArrayList}。 * * @return 包含目前項目的{@link ArrayList} */ default ArrayList<T> toArrayList() { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().remainingToArrayList(); } /** * 用目前項目值建立{@link ArrayList},依照條件做過濾。 * * @param <TException> 測試條件可拋出的例外型態 * @param condition 取得項目的條件測試函數 * @return 包含符合條件項目的{@link ArrayList} * @throws TException 表示{@code mapper}丟出例外 */ default <TException extends Exception> ArrayList<T> toArrayListFiltered( PredicateEx<? super T, ? extends TException> condition) throws TException { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().remainingToArrayListFiltered(condition); } /** * 用目前項目值建立{@link ArrayList},依照函數做對照。 * * @param <R> 對照項目型態 * @param <TException> 對照函數可拋出的例外型態 * @param mapper 對照項目的函數 * @return 包含目前項目對照結果的{@link ArrayList} * @throws TException 表示{@code mapper}丟出例外 */ default <R, TException extends Exception> ArrayList<R> toArrayListMapped( FunctionEx<? super T, ? extends R, ? extends TException> mapper) throws TException { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().remainingToArrayListMapped(mapper); } /** * 用目前項目值建立{@link ArrayList},依照鍵值做排序。 * * @param <V> 鍵值型態 * @param getKey 計算每個項目的鍵值 * @return 包含目前項目的{@link ArrayList},已排序 */ default <V extends Comparable<?>> ArrayList<T> toArrayListSorted(Function<? super T, ? extends V> getKey) { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().remainingToArrayListSorted(getKey); } /** * 用目前項目值建立{@link ArrayList},依照比較器做排序。 * * @param comparator 項目的比較器 * @return 包含目前項目的{@link ArrayList},已排序 */ default ArrayList<T> toArrayListSorted(Comparator<? super T> comparator) { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().remainingToArrayListSorted(comparator); } /** * 用目前項目值建立順序相反的{@link ArrayList}。 * * @return 包含目前項目的{@link ArrayList},順序相反 */ default ArrayList<T> toArrayListReversed() { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().remainingToArrayListReversed(); } /** * 用目前項目值建立{@link HashMap}。 * * @param <K> {@link HashMap}鍵值型態 * @param <KException> 計算鍵值函數可拋出的例外型態 * @param getKey 計算項目於新{@link HashMap}內的鍵值 * @return 包含目前項目對照結果的{@link HashMap} * @throws KException 表示{@code getKey}丟出例外 */ default <K, KException extends Exception> HashMap<K, T> toHashMap( FunctionEx<? super T, ? extends K, ? extends KException> getKey) throws KException { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().remainingToHashMap(getKey); } /** * 用目前項目值建立{@link HashMap}。 * * @param <K> {@link HashMap}鍵值型態 * @param <V> {@link HashMap}項目值型態 * @param <KException> 計算鍵值函數可拋出的例外型態 * @param <VException> 計算項目值函數可拋出的例外型態 * @param getKey 計算項目於新{@link HashMap}內的鍵值 * @param getValue 計算項目於新{@link HashMap}內的項目值 * @return 包含目前項目對照結果的{@link HashMap} * @throws KException 表示{@code getKey}丟出例外 * @throws VException 表示{@code getValue}丟出例外 */ default <K, V, KException extends Exception, VException extends Exception> HashMap<K, V> toHashMap( FunctionEx<? super T, ? extends K, ? extends KException> getKey, FunctionEx<? super T, ? extends V, ? extends VException> getValue) throws KException, VException { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().remainingToHashMap(getKey, getValue); } /** * 用目前項目值建立{@link HashMap},依照鍵值做分群。 * * @param <K> 分群鍵值型態 * @param <KException> 計算鍵值函數可拋出的例外型態 * @param getKey 計算每個項目的鍵值 * @return 包含目前項目分群組的{@link HashMap} * @throws KException 表示{@code getKey}丟出例外 */ default <K, KException extends Exception> HashMap<K, ArrayList<T>> toHashMapGrouped( FunctionEx<? super T, ? extends K, ? extends KException> getKey) throws KException { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().remainingToHashMapGrouped(getKey); } /** * 用目前項目值建立{@link HashMap},依照鍵值做分群。 * * @param <K> 群組鍵值型態 * @param <V> 項目值型態 * @param <KException> 計算鍵值函數可拋出的例外型態 * @param <VException> 計算項目值函數可拋出的例外型態 * @param getKey 計算每個項目做分組的鍵值 * @param getValue 計算項目於新{@link HashMap}內的項目值 * @return 包含目前項目分群組的{@link HashMap} * @throws KException 表示{@code getKey}丟出例外 * @throws VException 表示{@code getValue}丟出例外 */ default <K, V, KException extends Exception, VException extends Exception> HashMap<K, ArrayList<V>> toHashMapGrouped( FunctionEx<? super T, ? extends K, ? extends KException> getKey, FunctionEx<? super T, ? extends V, ? extends VException> getValue) throws KException, VException { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().remainingToHashMapGrouped(getKey, getValue); } /** * 用目前項目值建立{@link HashSet}。 * <p> * 重複值會被重疊覆蓋,後面的優先。 * </p> * * @return 包含目前項目的{@link HashSet} */ default HashSet<T> toHashSet() { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().remainingToHashSet(); } /** * 用目前項目值建立{@link TreeMap}。 * * @param <K> {@link TreeMap}鍵值型態 * @param <KException> 計算鍵值函數可拋出的例外型態 * @param getKey 計算項目於新{@link TreeMap}內的鍵值 * @return 包含目前項目對照結果的{@link TreeMap} * @throws KException 表示{@code getKey}丟出例外 */ default <K, KException extends Exception> TreeMap<K, T> toTreeMap( FunctionEx<? super T, ? extends K, ? extends KException> getKey) throws KException { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().remainingToTreeMap(getKey); } /** * 用目前項目值建立{@link TreeMap}。 * * @param <K> {@link TreeMap}鍵值型態 * @param <V> {@link TreeMap}項目值型態 * @param <KException> 計算鍵值函數可拋出的例外型態 * @param <VException> 計算項目值函數可拋出的例外型態 * @param getKey 計算項目於新{@link TreeMap}內的鍵值 * @param getValue 計算項目於新{@link TreeMap}內的項目值 * @return 包含目前項目對照結果的{@link TreeMap} * @throws KException 表示{@code getKey}丟出例外 * @throws VException 表示{@code getValue}丟出例外 */ default <K, V, KException extends Exception, VException extends Exception> TreeMap<K, V> toTreeMap( FunctionEx<? super T, ? extends K, ? extends KException> getKey, FunctionEx<? super T, ? extends V, ? extends VException> getValue) throws KException, VException { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().remainingToTreeMap(getKey, getValue); } /** * 用目前項目值建立{@link TreeMap},依照鍵值做分群。 * * @param <K> 分群鍵值型態 * @param <KException> 計算鍵值函數可拋出的例外型態 * @param getKey 計算每個項目的鍵值 * @return 包含目前項目分群組的{@link TreeMap} * @throws KException 表示{@code getKey}丟出例外 */ default <K, KException extends Exception> TreeMap<K, ArrayList<T>> toTreeMapGrouped( FunctionEx<? super T, ? extends K, ? extends KException> getKey) throws KException { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().remainingToTreeMapGrouped(getKey); } /** * 用目前項目值建立{@link TreeMap},依照鍵值做分群。 * * @param <K> 群組鍵值型態 * @param <V> 項目值型態 * @param <KException> 計算鍵值函數可拋出的例外型態 * @param <VException> 計算項目值函數可拋出的例外型態 * @param getKey 計算每個項目做分組的鍵值 * @param getValue 計算項目於新{@link TreeMap}內的項目值 * @return 包含目前項目分群組的{@link TreeMap} * @throws KException 表示{@code getKey}丟出例外 * @throws VException 表示{@code getValue}丟出例外 */ default <K, V, KException extends Exception, VException extends Exception> TreeMap<K, ArrayList<V>> toTreeMapGrouped( FunctionEx<? super T, ? extends K, ? extends KException> getKey, FunctionEx<? super T, ? extends V, ? extends VException> getValue) throws KException, VException { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().remainingToTreeMapGrouped(getKey, getValue); } /** * 用目前項目值建立{@link TreeSet}。 * <p> * 重複值會被重疊覆蓋,後面的優先。 * </p> * * @return 包含目前項目的{@link TreeSet} */ default TreeSet<T> toTreeSet() { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().remainingToTreeSet(); } ////////////////////////////////////////////////////////////////////////// // 數學統計 // /** * 進行歸約動作 * * @param <U> 歸約結果型態 * @param <TException> 累加函數可拋出的例外型態 * @param identity 初始值 * @param accumulator 累加函數 * @return 歸約結果 * @throws TException 表示{@code accumulator}丟出例外 */ default <U, TException extends Exception> U reduce( U identity, BiFunctionEx<U, ? super T, U, TException> accumulator) throws TException { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().reduceRemaining(identity, accumulator); } /** * 統計符合條件的項目數量。 * * @param <TException> 過濾條件函數可拋出的例外型態 * @param condition 過濾條件的函數 * @return 符合條件的項目數量 * @throws TException 表示{@code condition}丟出例外 */ default <TException extends Exception> int count(PredicateEx<? super T, ? extends TException> condition) throws TException { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().countRemaining(condition); } /** * 計算項目代表數值的平均。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 項目代表數值的平均,或null表示沒有項目 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> Double avgDouble( ToDoubleFunctionEx<? super T, ? extends TException> getValue) throws TException { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().avgRemainingDouble(getValue); } /** * 計算項目代表數值的平均。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 項目代表數值的平均,或null表示沒有項目 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> Integer avgInt(ToIntFunctionEx<? super T, ? extends TException> getValue) throws TException { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().avgRemainingInt(getValue); } /** * 計算項目代表數值的平均。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 項目代表數值的平均,或null表示沒有項目 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> Long avgLong(ToLongFunctionEx<? super T, ? extends TException> getValue) throws TException { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().avgRemainingLong(getValue); } /** * 計算項目代表數值的最大值。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 項目代表數值的最大值,或null表示沒有項目 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> Double maxDouble( ToDoubleFunctionEx<? super T, ? extends TException> getValue) throws TException { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().maxRemainingDouble(getValue); } /** * 計算項目代表數值的最大值。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 項目代表數值的最大值,或null表示沒有項目 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> Integer maxInt(ToIntFunctionEx<? super T, ? extends TException> getValue) throws TException { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().maxRemainingInt(getValue); } /** * 計算項目代表數值的最大值。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 項目代表數值的最大值,或null表示沒有項目 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> Long maxLong(ToLongFunctionEx<? super T, ? extends TException> getValue) throws TException { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().maxRemainingLong(getValue); } /** * 計算項目代表數值的最小值。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 項目代表數值的最小值,或null表示沒有項目 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> Double minDouble( ToDoubleFunctionEx<? super T, ? extends TException> getValue) throws TException { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().minRemainingDouble(getValue); } /** * 計算項目代表數值的最小值。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 項目代表數值的最小值,或null表示沒有項目 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> Integer minInt(ToIntFunctionEx<? super T, ? extends TException> getValue) throws TException { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().minRemainingInt(getValue); } /** * 計算項目代表數值的最小值。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 項目代表數值的最小值,或null表示沒有項目 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> Long minLong(ToLongFunctionEx<? super T, ? extends TException> getValue) throws TException { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().minRemainingLong(getValue); } /** * 計算項目代表數值的總和。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 項目代表數值的總和 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> double sumDouble( ToDoubleFunctionEx<? super T, ? extends TException> getValue) throws TException { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().sumRemainingDouble(getValue); } /** * 計算項目代表數值的總和。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 項目代表數值的總和 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> int sumInt(ToIntFunctionEx<? super T, ? extends TException> getValue) throws TException { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().sumRemainingInt(getValue); } /** * 計算項目代表數值的總和。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 項目代表數值的總和 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> long sumLong(ToIntFunctionEx<? super T, ? extends TException> getValue) throws TException { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().sumRemainingLong(getValue); } /** * 計算項目代表數值的總和。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 項目代表數值的總和 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> long sumLong(ToLongFunctionEx<? super T, ? extends TException> getValue) throws TException { Iterable<T> thiz = (Iterable<T>) this; return thiz.iterator().sumRemainingLong(getValue); } }