/* * 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.util; import java.lang.reflect.Array; 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; import jxtn.core.axi.comparators.MemberComparators; /** * {@link Iterator}的延伸功能。 * <p> * 添加延伸時應同步更新{@link java.lang.IterableExt}。 * </p> * * @author AqD * @param <E> 列舉項目型態 */ public interface IteratorExt<E> { /** * 結合多個列舉器。 * * @param <T> 列舉項目型態 * @param iterators 要結合的列舉器集合 * @return 結合的列舉器 */ @SafeVarargs static <T> Iterator<T> concatAll(Iterator<? extends T>... iterators) { return new ConcatedIterator<>(Arrays.asList(iterators).iterator()); } /** * 結合多個列舉器。 * * @param <T> 列舉項目型態 * @param iteratorIterable 要結合的列舉器的列舉 * @return 結合的列舉器 */ static <T> Iterator<T> concatAll(Iterable<Iterator<? extends T>> iteratorIterable) { return new ConcatedIterator<>(iteratorIterable.iterator()); } /** * 結合多個列舉器。 * * @param <T> 列舉項目型態 * @param iteratorIterator 要結合的列舉器的列舉器 * @return 結合的列舉器 */ static <T> Iterator<T> concatAll(Iterator<Iterator<? extends T>> iteratorIterator) { return new ConcatedIterator<>(iteratorIterator); } /** * 建立線性結構的串接列舉器。 * * @param <T> 列舉項目型態 * @param item 初始項目 * @param getNext 取得每個項目的下一個項目的函數,傳回null表示結尾 * @return 串接列舉器 */ static <T> Iterator<T> linkLine(T item, Function<? super T, ? extends T> getNext) { return new LinkLineIterator<>(item, getNext); } /** * 建立樹狀結構的串接列舉器。 * * @param <T> 列舉項目型態 * @param item 初始項目;根結點 * @param getChildren 取得每個項目的子項目集合,傳回null表示結尾 * @return 串接列舉器 */ static <T> Iterator<T> linkTree(T item, Function<? super T, ? extends Iterator<? extends T>> getChildren) { return new LinkTreeIterator<>(item, getChildren); } /** * 針對每個項目執行指定動作 * * @param <TException> 動作可拋出的例外型態 * @param action 要執行的動作 * @throws TException 表示{@code action}丟出例外 */ default <TException extends Exception> void forEachRemainingEx(ConsumerEx<? super E, ? extends TException> action) throws TException { Objects.requireNonNull(action); Iterator<E> thiz = (Iterator<E>) this; while (thiz.hasNext()) { action.acceptEx(thiz.next()); } } ////////////////////////////////////////////////////////////////////////// // 條件測試 // /** * 檢查是否所有剩餘項目皆符合指定條件。 * <p> * 結束後列舉器會停在結尾。 * </p> * * @param <TException> 測試條件可拋出的例外型態 * @param condition 條件測試的函數 * @return true表示符合,或沒有項目可測試false表示任一項目不符合 * @throws TException 表示{@code condition}丟出例外 */ default <TException extends Exception> boolean allRemaining(PredicateEx<? super E, ? extends TException> condition) throws TException { Iterator<E> thiz = (Iterator<E>) this; while (thiz.hasNext()) { E item = thiz.next(); if (!condition.testEx(item)) { return false; } } return true; } /** * 檢查是否有任一項目符合指定條件。 * <p> * 結束後列舉器會停在第一筆符合項目之後或是結尾。 * </p> * * @param <TException> 測試條件可拋出的例外型態 * @param condition 條件測試的函數 * @return true表示符合false表示所有項目皆不符合,或沒有項目可測試 * @throws TException 表示{@code condition}丟出例外 */ default <TException extends Exception> boolean anyRemaining(PredicateEx<? super E, ? extends TException> condition) throws TException { Iterator<E> thiz = (Iterator<E>) this; while (thiz.hasNext()) { E item = thiz.next(); if (condition.testEx(item)) { return true; } } return false; } ////////////////////////////////////////////////////////////////////////// // 列舉轉換 // /** * 將目前列舉器作為指定項目型態的列舉器傳回。 * * @param <V> 傳回項目型態 * @return 指定項目型態的列舉器(物件仍為目前列舉器) */ @SuppressWarnings("unchecked") default <V> Iterator<V> remainingAs() { return (Iterator<V>) this; } /** * 結合多個項目到結尾。 * * @param tailItems 要結合在結尾的其他項目 * @return 目前列舉及{@code tailItems}的結合 */ @SuppressWarnings("unchecked") default Iterator<E> appendToRemaining(E... tailItems) { List<Iterator<? extends E>> list = Arrays.asList( (Iterator<E>) this, Arrays.asList(tailItems).iterator()); return new ConcatedIterator<>(list.iterator()); } /** * 結合多個項目到開頭。 * * @param headItems 要結合在開頭的其他項目 * @return 目前列舉及{@code tailItems}的結合 */ @SuppressWarnings("unchecked") default Iterator<E> prependToRemaining(E... headItems) { List<Iterator<? extends E>> list = Arrays.asList( Arrays.asList(headItems).iterator(), (Iterator<E>) this); return new ConcatedIterator<>(list.iterator()); } /** * 結合多個列舉器。 * * @param iterators 要結合在後面的其他列舉器 * @return 目前列舉器及{@code iterators}的結合 */ @SuppressWarnings("unchecked") default Iterator<E> concatRemaining(Iterator<? extends E>... iterators) { List<Iterator<? extends E>> list = new ArrayList<>(iterators.length + 1); list.add((Iterator<E>) this); for (Iterator<? extends E> other : iterators) { list.add(other); } return new ConcatedIterator<>(list.iterator()); } /** * 依照展開函數建立展開列舉器。 * * @param <R> 展開項目型態 * @param expander 展開項目的函數 * @return 展開列舉器,依賴原有的列舉器 */ default <R> Iterator<R> expandRemaining(Function<? super E, Iterator<R>> expander) { Iterator<E> thiz = (Iterator<E>) this; return new ExpandedIterator<>(thiz, expander); } /** * 依照展開函數建立展開列舉器。 * * @param <R> 展開項目型態 * @param expander 展開項目的函數 * @return 展開列舉器,依賴原有的列舉器 */ default <R> Iterator<R> expandRemainingEx(FunctionEx<? super E, Iterator<R>, Exception> expander) { Iterator<E> thiz = (Iterator<E>) this; return new ExpandedIterator<>(thiz, expander); } /** * 依照條件建立過濾列舉器。 * * @param condition 過濾條件 * @return 過濾列舉器,依賴原有的列舉器 */ default Iterator<E> filterRemaining(Predicate<? super E> condition) { Iterator<E> thiz = (Iterator<E>) this; return new FilteredIterator<>(thiz, condition); } /** * 依照條件建立過濾列舉器。 * * @param condition 過濾條件 * @return 過濾列舉器,依賴原有的列舉器 */ default Iterator<E> filterRemainingEx(PredicateEx<? super E, Exception> condition) { Iterator<E> thiz = (Iterator<E>) this; return new FilteredIterator<>(thiz, condition); } /** * 依照條件建立剔除開頭的列舉器。 * <p> * 列舉內容只保留第一個符合條件後的所有項目(包含該項目)。 * </p> * * @param condition 過濾條件 * @return 過濾列舉器,依賴原有的列舉器 */ default Iterator<E> remainingAfter(Predicate<? super E> condition) { Iterator<E> thiz = (Iterator<E>) this; return new AfterConditionIterator<>(thiz, condition); } /** * 依照條件建立剔除開頭的列舉器。 * <p> * 列舉內容只保留第一個符合條件後的所有項目(包含該項目)。 * </p> * * @param condition 過濾條件 * @return 過濾列舉器,依賴原有的列舉器 */ default Iterator<E> remainingAfterEx(PredicateEx<? super E, Exception> condition) { Iterator<E> thiz = (Iterator<E>) this; return new AfterConditionIterator<>(thiz, condition); } /** * 依照條件建立剔除結尾的列舉器。 * <p> * 列舉內容只保留第一個符合條件前的所有項目(不含該項目)。 * </p> * * @param condition 過濾條件 * @return 過濾列舉器,依賴原有的列舉器 */ default Iterator<E> remainingBefore(Predicate<? super E> condition) { Iterator<E> thiz = (Iterator<E>) this; return new BeforeConditionIterator<>(thiz, condition); } /** * 依照條件建立剔除結尾的列舉器。 * <p> * 列舉內容只保留第一個符合條件前的所有項目(不含該項目)。 * </p> * * @param condition 過濾條件 * @return 過濾列舉器,依賴原有的列舉器 */ default Iterator<E> remainingBefore(PredicateEx<? super E, Exception> condition) { Iterator<E> thiz = (Iterator<E>) this; return new BeforeConditionIterator<>(thiz, condition); } /** * 建立加上索引的列舉器。 * * @return 加上索引的列舉器,依賴原有的列舉器 */ default Iterator<IndexedItem<E>> remainingIndexed() { Iterator<E> thiz = (Iterator<E>) this; return new IndexedIterator<>(thiz); } /** * 依照對照函數建立對照列舉器。 * * @param <R> 對照項目型態 * @param mapper 對照項目的函數 * @return 對照列舉器,依賴原有的列舉器 */ default <R> Iterator<R> mapRemaining(Function<? super E, ? extends R> mapper) { Iterator<E> thiz = (Iterator<E>) this; return new MappedIterator<>(thiz, mapper); } /** * 依照對照函數建立對照列舉器。 * * @param <R> 對照項目型態 * @param mapper 對照項目的函數 * @return 對照列舉器,依賴原有的列舉器 */ default <R> Iterator<R> mapRemainingEx(FunctionEx<? super E, ? extends R, Exception> mapper) { Iterator<E> thiz = (Iterator<E>) this; return new MappedIterator<>(thiz, mapper); } /** * 建立只包含指定型態項目的列舉器。 * * @param <R> 要取得項目的型態 * @param type 要取得項目的型態 * @return 只包含{@code type}型態項目的列舉 */ @SuppressWarnings("unchecked") default <R> Iterator<R> remainingOfType(Class<? extends R> type) { Iterator<E> thiz = (Iterator<E>) this; return thiz.filterRemaining(type::isInstance).mapRemaining(e -> (R) e); } /** * 建立跳過指定項目數量的列舉器。 * * @param count 要跳過的項目數量 * @return 跳過指定數量的列舉器,依賴原有的列舉器 */ default Iterator<E> skipRemaining(int count) { Iterator<E> thiz = (Iterator<E>) this; return new SkippedIterator<>(thiz, count); } ////////////////////////////////////////////////////////////////////////// // 項目挑選 // /** * 取得符合條件的下一筆項目。 * <p> * 結束後列舉器會停在第一筆符合項目之後或是結尾。 * </p> * * @param <TException> 測試條件可拋出的例外型態 * @param condition 取得項目的條件測試函數 * @return 符合條件的下一筆項目 * @throws NoSuchElementException 沒有下一筆或符合條件的項目 * @throws TException 表示{@code condition}丟出例外 */ default <TException extends Exception> E next(PredicateEx<? super E, ? extends TException> condition) throws TException { Iterator<E> thiz = (Iterator<E>) this; while (thiz.hasNext()) { E item = thiz.next(); if (condition.testEx(item)) { return item; } } throw new NoSuchElementException(); } /** * 取得下一筆項目或null。 * <p> * 結束後列舉器會停在第一筆符合項目之後或是結尾。 * </p> * * @return 下一筆項目,或null表示沒有下一筆項目 */ default E nextOrNull() { Iterator<E> thiz = (Iterator<E>) this; if (thiz.hasNext()) { return thiz.next(); } return null; } /** * 取得符合條件的下一筆項目或null。 * <p> * 結束後列舉器會停在第一筆符合項目之後或是結尾。 * </p> * * @param <TException> 測試條件可拋出的例外型態 * @param condition 取得項目的條件測試函數 * @return 符合條件的下一筆項目,或null表示沒有下一筆或符合條件的項目 * @throws TException 表示{@code condition}丟出例外 */ default <TException extends Exception> E nextOrNull(PredicateEx<? super E, ? extends TException> condition) throws TException { Iterator<E> thiz = (Iterator<E>) this; while (thiz.hasNext()) { E item = thiz.next(); if (condition.testEx(item)) { return item; } } return null; } /** * 取得第N筆項目。 * * @param position 位置(相對於目前位置) * @return 第N筆項目 * @throws NoSuchElementException 沒有第N筆項目 */ default E nextNth(int position) { Iterator<E> thiz = (Iterator<E>) this; for (int i = 0; i < position; i++) { thiz.next(); } return thiz.next(); } /** * 取得第N筆項目或null。 * * @param position 位置(相對於目前位置) * @return 第N筆項目,或null表示沒有第N筆項目 */ default E nextNthOrNull(int position) { Iterator<E> thiz = (Iterator<E>) this; for (int i = 0; i < position; i++) { if (!thiz.hasNext()) { return null; } thiz.next(); } if (!thiz.hasNext()) { return null; } return thiz.next(); } /** * 取得下一個可計算出最大數值的項目。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param <V> 數值型態 * @param getValue 計算項目數值的函數 * @return 下一個計算出最大數值的項目(跳過NULL數值) * @throws NoSuchElementException 沒有下一筆項目 * @throws TException 表示{@code getValue}丟出例外 */ default <V extends Comparable<? super V>, TException extends Exception> E nextOfMax( FunctionEx<? super E, ? extends V, ? extends TException> getValue) throws TException { Iterator<E> thiz = (Iterator<E>) this; if (!thiz.hasNext()) { throw new NoSuchElementException(); } E maxE = thiz.next(); V maxV = getValue.applyEx(maxE); while (thiz.hasNext()) { E curE = thiz.next(); V curV = getValue.applyEx(curE); if (maxV == null || maxV.compareTo(curV) < 0) { maxV = curV; maxE = curE; } } return maxE; } /** * 取得下一個可計算出最大數值的項目。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 下一個計算出最大數值的項目 * @throws NoSuchElementException 沒有下一筆項目 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> E nextOfMaxDouble( ToDoubleFunctionEx<? super E, ? extends TException> getValue) throws TException { Iterator<E> thiz = (Iterator<E>) this; if (!thiz.hasNext()) { throw new NoSuchElementException(); } E maxE = thiz.next(); double maxV = getValue.applyAsDoubleEx(maxE); while (thiz.hasNext()) { E curE = thiz.next(); double curV = getValue.applyAsDoubleEx(curE); if (maxV < curV) { maxV = curV; maxE = curE; } } return maxE; } /** * 取得下一個可計算出最大數值的項目。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 下一個計算出最大數值的項目 * @throws NoSuchElementException 沒有下一筆項目 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> E nextOfMaxInt(ToIntFunctionEx<? super E, ? extends TException> getValue) throws TException { Iterator<E> thiz = (Iterator<E>) this; if (!thiz.hasNext()) { throw new NoSuchElementException(); } E maxE = thiz.next(); int maxV = getValue.applyAsIntEx(maxE); while (thiz.hasNext()) { E curE = thiz.next(); int curV = getValue.applyAsIntEx(curE); if (maxV < curV) { maxV = curV; maxE = curE; } } return maxE; } /** * 取得下一個可計算出最大數值的項目。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 下一個計算出最大數值的項目 * @throws NoSuchElementException 沒有下一筆項目 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> E nextOfMaxLong(ToLongFunctionEx<? super E, ? extends TException> getValue) throws TException { Iterator<E> thiz = (Iterator<E>) this; if (!thiz.hasNext()) { throw new NoSuchElementException(); } E maxE = thiz.next(); long maxV = getValue.applyAsLongEx(maxE); while (thiz.hasNext()) { E curE = thiz.next(); long curV = getValue.applyAsLongEx(curE); if (maxV < curV) { maxV = curV; maxE = curE; } } return maxE; } /** * 取得下一個可計算出最小數值的項目。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param <V> 數值型態 * @param getValue 計算項目數值的函數 * @return 下一個計算出最小數值的項目(跳過NULL數值) * @throws NoSuchElementException 沒有下一筆項目 * @throws TException 表示{@code getValue}丟出例外 */ default <V extends Comparable<? super V>, TException extends Exception> E nextOfMin( FunctionEx<? super E, ? extends V, ? extends TException> getValue) throws TException { Iterator<E> thiz = (Iterator<E>) this; if (!thiz.hasNext()) { throw new NoSuchElementException(); } E minE = thiz.next(); V minV = getValue.applyEx(minE); while (thiz.hasNext()) { E curE = thiz.next(); V curV = getValue.applyEx(curE); if (minV == null || minV.compareTo(curV) > 0) { minV = curV; minE = curE; } } return minE; } /** * 取得下一個可計算出最小數值的項目。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 下一個計算出最小數值的項目 * @throws NoSuchElementException 沒有下一筆項目 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> E nextOfMinDouble( ToDoubleFunctionEx<? super E, ? extends TException> getValue) throws TException { Iterator<E> thiz = (Iterator<E>) this; if (!thiz.hasNext()) { throw new NoSuchElementException(); } E minE = thiz.next(); double minV = getValue.applyAsDoubleEx(minE); while (thiz.hasNext()) { E curE = thiz.next(); double curV = getValue.applyAsDoubleEx(curE); if (minV > curV) { minV = curV; minE = curE; } } return minE; } /** * 取得下一個可計算出最小數值的項目。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 下一個計算出最小數值的項目 * @throws NoSuchElementException 沒有下一筆項目 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> E nextOfMinInt(ToIntFunctionEx<? super E, ? extends TException> getValue) throws TException { Iterator<E> thiz = (Iterator<E>) this; if (!thiz.hasNext()) { throw new NoSuchElementException(); } E minE = thiz.next(); int minV = getValue.applyAsIntEx(minE); while (thiz.hasNext()) { E curE = thiz.next(); int curV = getValue.applyAsIntEx(curE); if (minV > curV) { minV = curV; minE = curE; } } return minE; } /** * 取得下一個可計算出最小數值的項目。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 下一個計算出最小數值的項目 * @throws NoSuchElementException 沒有下一筆項目 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> E nextOfMinLong(ToLongFunctionEx<? super E, ? extends TException> getValue) throws TException { Iterator<E> thiz = (Iterator<E>) this; if (!thiz.hasNext()) { throw new NoSuchElementException(); } E minE = thiz.next(); long minV = getValue.applyAsLongEx(minE); while (thiz.hasNext()) { E curE = thiz.next(); long curV = getValue.applyAsLongEx(curE); if (minV > curV) { minV = curV; minE = curE; } } return minE; } /** * 取得最後一筆項目。 * <p> * 結束後列舉器會停在結尾。 * </p> * * @return 最後一筆項目 * @throws NoSuchElementException 沒有下一筆項目 */ default E lastOfRemaining() { Iterator<E> thiz = (Iterator<E>) this; boolean lastFound = false; E lastMatched = null; while (thiz.hasNext()) { lastFound = true; lastMatched = thiz.next(); } if (lastFound) { return lastMatched; } else { throw new NoSuchElementException(); } } /** * 取得符合條件的最後一筆項目。 * <p> * 結束後列舉器會停在結尾。 * </p> * * @param <TException> 測試條件可拋出的例外型態 * @param condition 取得項目的條件測試函數 * @return 最後一筆符合條件的項目 * @throws NoSuchElementException 沒有任何符合條件的項目 * @throws TException 表示{@code condition}丟出例外 */ default <TException extends Exception> E lastOfRemaining(PredicateEx<? super E, ? extends TException> condition) throws TException { Iterator<E> thiz = (Iterator<E>) this; boolean lastFound = false; E lastMatched = null; while (thiz.hasNext()) { E item = thiz.next(); if (condition.testEx(item)) { lastFound = true; lastMatched = item; } } if (lastFound) { return lastMatched; } else { throw new NoSuchElementException(); } } /** * 取得最後一筆項目或null。 * <p> * 結束後列舉器會停在結尾。 * </p> * * @return 最後一筆項目,或null表示沒有任何項目 */ default E lastOfRemainingOrNull() { Iterator<E> thiz = (Iterator<E>) this; E lastMatched = null; while (thiz.hasNext()) { lastMatched = thiz.next(); } return lastMatched; } /** * 取得符合條件的最後一筆項目。 * <p> * 結束後列舉器會停在結尾。 * </p> * * @param <TException> 測試條件可拋出的例外型態 * @param condition 取得項目的條件測試函數 * @return 符合條件的最後一筆項目,或null表示沒有任何符合條件的項目 * @throws TException 表示{@code condition}丟出例外 */ default <TException extends Exception> E lastOfRemainingOrNull(PredicateEx<? super E, ? extends TException> condition) throws TException { Iterator<E> thiz = (Iterator<E>) this; E lastMatched = null; while (thiz.hasNext()) { E item = thiz.next(); if (condition.testEx(item)) { lastMatched = item; } } return lastMatched; } ////////////////////////////////////////////////////////////////////////// // 項目統整 // /** * 用目前項目值建立陣列。 * * @param type 陣列項目型態 * @return 包含目前項目的陣列 */ @SuppressWarnings("unchecked") default E[] remainingToArray(Class<E> type) { Iterator<E> thiz = (Iterator<E>) this; ArrayList<E> list = thiz.remainingToArrayList(); E[] array = (E[]) Array.newInstance(type, list.size()); return list.toArray(array); } /** * 用目前項目值建立{@link ArrayList}。 * * @return 包含目前項目的{@link ArrayList} */ default ArrayList<E> remainingToArrayList() { Iterator<E> thiz = (Iterator<E>) this; ArrayList<E> coll = new ArrayList<>(); while (thiz.hasNext()) { coll.add(thiz.next()); } return coll; } /** * 用目前項目值建立{@link ArrayList},依照條件做過濾。 * * @param <TException> 測試條件可拋出的例外型態 * @param condition 取得項目的條件測試函數 * @return 包含符合條件項目的{@link ArrayList} * @throws TException 表示{@code mapper}丟出例外 */ default <TException extends Exception> ArrayList<E> remainingToArrayListFiltered( PredicateEx<? super E, ? extends TException> condition) throws TException { Iterator<E> thiz = (Iterator<E>) this; ArrayList<E> coll = new ArrayList<>(); while (thiz.hasNext()) { E e = thiz.next(); if (condition.testEx(e)) { coll.add(e); } } return coll; } /** * 用目前項目值建立{@link ArrayList},依照函數做對照。 * * @param <R> 對照項目型態 * @param <TException> 對照函數可拋出的例外型態 * @param mapper 對照項目的函數 * @return 包含目前項目對照結果的{@link ArrayList} * @throws TException 表示{@code mapper}丟出例外 */ default <R, TException extends Exception> ArrayList<R> remainingToArrayListMapped( FunctionEx<? super E, ? extends R, ? extends TException> mapper) throws TException { Iterator<E> thiz = (Iterator<E>) this; ArrayList<R> coll = new ArrayList<>(); while (thiz.hasNext()) { coll.add(mapper.applyEx(thiz.next())); } return coll; } /** * 用目前項目值建立{@link ArrayList},依照鍵值做排序。 * * @param <V> 鍵值型態 * @param getKey 計算每個項目的鍵值 * @return 包含目前項目的{@link ArrayList},已排序 */ default <V extends Comparable<?>> ArrayList<E> remainingToArrayListSorted(Function<? super E, ? extends V> getKey) { Iterator<E> thiz = (Iterator<E>) this; ArrayList<E> sorted = thiz.remainingToArrayList(); sorted.sort(MemberComparators.byComparable(getKey)); return sorted; } /** * 用目前項目值建立{@link ArrayList},依照比較器做排序。 * * @param comparator 項目的比較器 * @return 包含目前項目的{@link ArrayList},已排序 */ default ArrayList<E> remainingToArrayListSorted(Comparator<? super E> comparator) { Iterator<E> thiz = (Iterator<E>) this; ArrayList<E> sorted = thiz.remainingToArrayList(); sorted.sort(comparator); return sorted; } /** * 用目前項目值建立順序相反的{@link ArrayList}。 * * @return 包含目前項目的{@link ArrayList},順序相反 */ default ArrayList<E> remainingToArrayListReversed() { Iterator<E> thiz = (Iterator<E>) this; ArrayList<E> reversed = thiz.remainingToArrayList(); Collections.reverse(reversed); return reversed; } /** * 用目前項目值建立{@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, E> remainingToHashMap( FunctionEx<? super E, ? extends K, ? extends KException> getKey) throws KException { Iterator<E> thiz = (Iterator<E>) this; HashMap<K, E> coll = new HashMap<>(); while (thiz.hasNext()) { E item = thiz.next(); K k = getKey.applyEx(item); coll.put(k, item); } return coll; } /** * 用目前項目值建立{@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> remainingToHashMap( FunctionEx<? super E, ? extends K, ? extends KException> getKey, FunctionEx<? super E, ? extends V, ? extends VException> getValue) throws KException, VException { Iterator<E> thiz = (Iterator<E>) this; HashMap<K, V> coll = new HashMap<>(); while (thiz.hasNext()) { E item = thiz.next(); K k = getKey.applyEx(item); V v = getValue.applyEx(item); coll.put(k, v); } return coll; } /** * 用目前項目值建立{@link HashMap},依照鍵值做分群。 * * @param <K> 分群鍵值型態 * @param <KException> 計算鍵值函數可拋出的例外型態 * @param getKey 計算每個項目的鍵值 * @return 包含目前項目分群組的{@link HashMap} * @throws KException 表示{@code getKey}丟出例外 */ default <K, KException extends Exception> HashMap<K, ArrayList<E>> remainingToHashMapGrouped( FunctionEx<? super E, ? extends K, ? extends KException> getKey) throws KException { Iterator<E> thiz = (Iterator<E>) this; HashMap<K, ArrayList<E>> result = new HashMap<>(); while (thiz.hasNext()) { E item = thiz.next(); K key = getKey.applyEx(item); ArrayList<E> list = result.get(key); if (list == null) { list = new ArrayList<>(); result.put(key, list); } list.add(item); } return result; } /** * 用目前項目值建立{@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>> remainingToHashMapGrouped( FunctionEx<? super E, ? extends K, ? extends KException> getKey, FunctionEx<? super E, ? extends V, ? extends VException> getValue) throws KException, VException { Iterator<E> thiz = (Iterator<E>) this; HashMap<K, ArrayList<V>> result = new HashMap<>(); while (thiz.hasNext()) { E item = thiz.next(); K key = getKey.applyEx(item); ArrayList<V> list = result.get(key); if (list == null) { list = new ArrayList<>(); result.put(key, list); } V value = getValue.applyEx(item); list.add(value); } return result; } /** * 用目前項目值建立{@link HashSet}。 * <p> * 重複值會被重疊覆蓋,後面的優先。 * </p> * * @return 包含目前項目的{@link HashSet} */ default HashSet<E> remainingToHashSet() { Iterator<E> thiz = (Iterator<E>) this; HashSet<E> coll = new HashSet<>(); while (thiz.hasNext()) { coll.add(thiz.next()); } return coll; } /** * 用目前項目值建立{@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, E> remainingToTreeMap( FunctionEx<? super E, ? extends K, ? extends KException> getKey) throws KException { Iterator<E> thiz = (Iterator<E>) this; TreeMap<K, E> coll = new TreeMap<>(); while (thiz.hasNext()) { E item = thiz.next(); K k = getKey.applyEx(item); coll.put(k, item); } return coll; } /** * 用目前項目值建立{@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> remainingToTreeMap( FunctionEx<? super E, ? extends K, ? extends KException> getKey, FunctionEx<? super E, ? extends V, ? extends VException> getValue) throws KException, VException { Iterator<E> thiz = (Iterator<E>) this; TreeMap<K, V> coll = new TreeMap<>(); while (thiz.hasNext()) { E item = thiz.next(); K k = getKey.applyEx(item); V v = getValue.applyEx(item); coll.put(k, v); } return coll; } /** * 用目前項目值建立{@link TreeMap},依照鍵值做分群。 * * @param <K> 分群鍵值型態 * @param <KException> 計算鍵值函數可拋出的例外型態 * @param getKey 計算每個項目的鍵值 * @return 包含目前項目分群組的{@link TreeMap} * @throws KException 表示{@code getKey}丟出例外 */ default <K, KException extends Exception> TreeMap<K, ArrayList<E>> remainingToTreeMapGrouped( FunctionEx<? super E, ? extends K, ? extends KException> getKey) throws KException { Iterator<E> thiz = (Iterator<E>) this; TreeMap<K, ArrayList<E>> result = new TreeMap<>(); while (thiz.hasNext()) { E item = thiz.next(); K key = getKey.applyEx(item); ArrayList<E> list = result.get(key); if (list == null) { list = new ArrayList<>(); result.put(key, list); } list.add(item); } return result; } /** * 用目前項目值建立{@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>> remainingToTreeMapGrouped( FunctionEx<? super E, ? extends K, ? extends KException> getKey, FunctionEx<? super E, ? extends V, ? extends VException> getValue) throws KException, VException { Iterator<E> thiz = (Iterator<E>) this; TreeMap<K, ArrayList<V>> result = new TreeMap<>(); while (thiz.hasNext()) { E item = thiz.next(); K key = getKey.applyEx(item); ArrayList<V> list = result.get(key); if (list == null) { list = new ArrayList<>(); result.put(key, list); } V value = getValue.applyEx(item); list.add(value); } return result; } /** * 用目前項目值建立{@link TreeSet}。 * <p> * 重複值會被重疊覆蓋,後面的優先。 * </p> * * @return 包含目前項目的{@link TreeSet} */ default TreeSet<E> remainingToTreeSet() { Iterator<E> thiz = (Iterator<E>) this; TreeSet<E> coll = new TreeSet<>(); while (thiz.hasNext()) { coll.add(thiz.next()); } return coll; } ////////////////////////////////////////////////////////////////////////// // 數學統計 // /** * 進行歸約動作 * * @param <U> 歸約結果型態 * @param <TException> 累加函數可拋出的例外型態 * @param identity 初始值 * @param accumulator 累加函數 * @return 歸約結果 * @throws TException 表示{@code accumulator}丟出例外 */ default <U, TException extends Exception> U reduceRemaining( U identity, BiFunctionEx<U, ? super E, U, TException> accumulator) throws TException { Iterator<E> thiz = (Iterator<E>) this; U result = identity; while (thiz.hasNext()) { E e = thiz.next(); result = accumulator.applyEx(result, e); } return result; } /** * 統計符合條件的項目數量。 * * @param <TException> 過濾條件函數可拋出的例外型態 * @param condition 過濾條件的函數 * @return 符合條件的項目數量 * @throws TException 表示{@code condition}丟出例外 */ default <TException extends Exception> int countRemaining(PredicateEx<? super E, ? extends TException> condition) throws TException { Iterator<E> thiz = (Iterator<E>) this; int count = 0; while (thiz.hasNext()) { E e = thiz.next(); if (condition.testEx(e)) { count += 1; } } return count; } /** * 計算項目代表數值的平均。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 項目代表數值的平均,或null表示沒有項目 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> Double avgRemainingDouble( ToDoubleFunctionEx<? super E, ? extends TException> getValue) throws TException { Iterator<E> thiz = (Iterator<E>) this; double total = 0; double count = 0; while (thiz.hasNext()) { E e = thiz.next(); double v = getValue.applyAsDoubleEx(e); total += v; count += 1; } if (count > 0) { return total / count; } else { return null; } } /** * 計算項目代表數值的平均。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 項目代表數值的平均,或null表示沒有項目 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> Integer avgRemainingInt(ToIntFunctionEx<? super E, ? extends TException> getValue) throws TException { Iterator<E> thiz = (Iterator<E>) this; double total = 0; double count = 0; while (thiz.hasNext()) { E e = thiz.next(); int v = getValue.applyAsIntEx(e); total += v; count += 1; } if (count > 0) { return Math.round((float) (total / count)); } else { return null; } } /** * 計算項目代表數值的平均。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 項目代表數值的平均,或null表示沒有項目 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> Long avgRemainingLong(ToLongFunctionEx<? super E, ? extends TException> getValue) throws TException { Iterator<E> thiz = (Iterator<E>) this; double total = 0; double count = 0; while (thiz.hasNext()) { E e = thiz.next(); long v = getValue.applyAsLongEx(e); total += v; count += 1; } if (count > 0) { return Math.round(total / count); } else { return null; } } /** * 計算項目代表數值的最大值。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 項目代表數值的最大值,或null表示沒有項目 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> Double maxRemainingDouble( ToDoubleFunctionEx<? super E, ? extends TException> getValue) throws TException { Iterator<E> thiz = (Iterator<E>) this; Double maxValue = null; while (thiz.hasNext()) { E e = thiz.next(); double v = getValue.applyAsDoubleEx(e); if (maxValue == null || maxValue < v) { maxValue = v; } } return maxValue; } /** * 計算項目代表數值的最大值。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 項目代表數值的最大值,或null表示沒有項目 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> Integer maxRemainingInt(ToIntFunctionEx<? super E, ? extends TException> getValue) throws TException { Iterator<E> thiz = (Iterator<E>) this; Integer maxValue = null; while (thiz.hasNext()) { E e = thiz.next(); int v = getValue.applyAsIntEx(e); if (maxValue == null || maxValue < v) { maxValue = v; } } return maxValue; } /** * 計算項目代表數值的最大值。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 項目代表數值的最大值,或null表示沒有項目 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> Long maxRemainingLong(ToLongFunctionEx<? super E, ? extends TException> getValue) throws TException { Iterator<E> thiz = (Iterator<E>) this; Long maxValue = null; while (thiz.hasNext()) { E e = thiz.next(); long v = getValue.applyAsLongEx(e); if (maxValue == null || maxValue < v) { maxValue = v; } } return maxValue; } /** * 計算項目代表數值的最小值。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 項目代表數值的最小值,或null表示沒有項目 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> Double minRemainingDouble( ToDoubleFunctionEx<? super E, ? extends TException> getValue) throws TException { Iterator<E> thiz = (Iterator<E>) this; Double minValue = null; while (thiz.hasNext()) { E e = thiz.next(); double v = getValue.applyAsDoubleEx(e); if (minValue == null || minValue > v) { minValue = v; } } return minValue; } /** * 計算項目代表數值的最小值。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 項目代表數值的最小值,或null表示沒有項目 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> Integer minRemainingInt(ToIntFunctionEx<? super E, ? extends TException> getValue) throws TException { Iterator<E> thiz = (Iterator<E>) this; Integer minValue = null; while (thiz.hasNext()) { E e = thiz.next(); int v = getValue.applyAsIntEx(e); if (minValue == null || minValue > v) { minValue = v; } } return minValue; } /** * 計算項目代表數值的最小值。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 項目代表數值的最小值,或null表示沒有項目 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> Long minRemainingLong(ToLongFunctionEx<? super E, ? extends TException> getValue) throws TException { Iterator<E> thiz = (Iterator<E>) this; Long minValue = null; while (thiz.hasNext()) { E e = thiz.next(); long v = getValue.applyAsLongEx(e); if (minValue == null || minValue > v) { minValue = v; } } return minValue; } /** * 計算項目代表數值的總和。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 項目代表數值的總和,或null表示沒有項目 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> double sumRemainingDouble( ToDoubleFunctionEx<? super E, ? extends TException> getValue) throws TException { Iterator<E> thiz = (Iterator<E>) this; double sumValue = 0; while (thiz.hasNext()) { E e = thiz.next(); sumValue += getValue.applyAsDoubleEx(e); } return sumValue; } /** * 計算項目代表數值的總和。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 項目代表數值的總和 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> int sumRemainingInt(ToIntFunctionEx<? super E, ? extends TException> getValue) throws TException { Iterator<E> thiz = (Iterator<E>) this; int sumValue = 0; while (thiz.hasNext()) { E e = thiz.next(); sumValue += getValue.applyAsIntEx(e); } return sumValue; } /** * 計算項目代表數值的總和。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 項目代表數值的總和 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> long sumRemainingLong(ToIntFunctionEx<? super E, ? extends TException> getValue) throws TException { Iterator<E> thiz = (Iterator<E>) this; long sumValue = 0; while (thiz.hasNext()) { E e = thiz.next(); sumValue += getValue.applyAsIntEx(e); } return sumValue; } /** * 計算項目代表數值的總和。 * * @param <TException> 計算數值函數可拋出的例外型態 * @param getValue 計算項目數值的函數 * @return 項目代表數值的總和 * @throws TException 表示{@code getValue}丟出例外 */ default <TException extends Exception> long sumRemainingLong(ToLongFunctionEx<? super E, ? extends TException> getValue) throws TException { Iterator<E> thiz = (Iterator<E>) this; long sumValue = 0; while (thiz.hasNext()) { E e = thiz.next(); sumValue += getValue.applyAsLongEx(e); } return sumValue; } }