/** * Calculates the average of this elements. Returns {@code None} if this is empty, otherwise * {@code Some(average)}. Supported component types are {@code Byte}, {@code Double}, {@code * Float}, {@code Integer}, {@code Long}, {@code Short}, {@code BigInteger} and {@code * BigDecimal}. * * <p>Examples: * * <pre> * <code> * List.empty().average() // = None * List.of(1, 2, 3).average() // = Some(2.0) * List.of(0.1, 0.2, 0.3).average() // = Some(0.2) * List.of("apple", "pear").average() // throws * </code> * </pre> * * @return {@code Some(average)} or {@code None}, if there are no elements * @throws UnsupportedOperationException if this elements are not numeric */ @SuppressWarnings("unchecked") default Option<Double> average() { if (isEmpty()) { return None.instance(); } else { final TraversableOnce<?> objects = isTraversableAgain() ? this : toStream(); final Object head = objects.head(); final double d; if (head instanceof Integer || head instanceof Short || head instanceof Byte) { d = ((TraversableOnce<Number>) objects) .toJavaStream() .mapToInt(Number::intValue) .average() .getAsDouble(); } else if (head instanceof Double || head instanceof Float || head instanceof BigDecimal) { d = ((TraversableOnce<Number>) objects) .toJavaStream() .mapToDouble(Number::doubleValue) .average() .getAsDouble(); } else if (head instanceof Long || head instanceof BigInteger) { d = ((TraversableOnce<Number>) objects) .toJavaStream() .mapToLong(Number::longValue) .average() .getAsDouble(); } else { throw new UnsupportedOperationException("not numeric"); } return new Some<>(d); } }
/** * Calculates the minimum of this elements within the co-domain of a specific function. * * @param f A function that maps this elements to comparable elements * @param <U> The type where elements are compared * @return The element of type T which is the minimum within U */ default <U extends Comparable<? super U>> Option<T> minBy(Function<? super T, ? extends U> f) { Objects.requireNonNull(f, "f is null"); if (isEmpty()) { return None.instance(); } else { return minBy((t1, t2) -> f.apply(t1).compareTo(f.apply(t2))); } }
@Override public Option<HashMap<K, V>> tailOption() { if (trie.isEmpty()) { return None.instance(); } else { return new Some<>(tail()); } }
@Override public Option<HashMap<K, V>> initOption() { if (isEmpty()) { return None.instance(); } else { return new Some<>(init()); } }
@Override public Option<? extends Vector<T>> initOption() { if (isEmpty()) { return None.instance(); } else { return new Some<>(init()); } }
@Override public Option<T> headOption() { if (isEmpty()) { return None.instance(); } else { return new Some<>(get(0)); } }
/** * Calculates the minimum of this elements using a specific comparator. * * @param comparator A non-null element comparator * @return {@code Some(minimum)} of this elements or {@code None} if this is empty * @throws NullPointerException if {@code comparator} is null */ default Option<T> minBy(Comparator<? super T> comparator) { Objects.requireNonNull(comparator, "comparator is null"); if (isEmpty()) { return None.instance(); } else { final T value = reduce((t1, t2) -> comparator.compare(t1, t2) <= 0 ? t1 : t2); return new Some<>(value); } }
/** * Calculates the minimum of this elements according to their natural order. * * @return {@code Some(minimum)} of this elements or {@code None} if this is empty or this * elements are not comparable */ @SuppressWarnings("unchecked") default Option<T> min() { final Stream<T> stream = Stream.ofAll(iterator()); if (isEmpty() || !(stream.head() instanceof Comparable)) { return None.instance(); } else { return stream.minBy((o1, o2) -> ((Comparable<T>) o1).compareTo(o2)); } }
@Override public Option<Vector<T>> tailOption() { if (isEmpty()) { return None.instance(); } HashArrayMappedTrie<Integer, T> trie = HashArrayMappedTrie.empty(); for (int i = 1; i < length(); i++) { trie = trie.put(i - 1, get(i)); } return new Some<>(trie.isEmpty() ? empty() : new Vector<>(trie)); }
/** * Dual of {@linkplain #headOption()}, returning the last element as {@code Opiton}. * * @return {@code Some(element)} or {@code None} if this is empty. */ default Option<T> lastOption() { return isEmpty() ? None.instance() : new Some<>(last()); }
@Override public Option<Tuple2<K, V>> headOption() { return isEmpty() ? None.instance() : new Some<>(head()); }