
net.codestory.http.misc.Fluent Maven / Gradle / Ivy
/**
* Copyright (C) 2013 [email protected]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package net.codestory.http.misc;
import static java.util.Objects.*;
import java.util.*;
import java.util.function.*;
import java.util.stream.*;
@FunctionalInterface
public interface Fluent extends Iterable {
Stream stream();
static Fluent of() {
return Stream::empty;
}
@SafeVarargs
static Fluent of(T... values) {
requireNonNull(values);
return () -> Stream.of(values);
}
static Fluent of(int[] values) {
requireNonNull(values);
return () -> IntStream.of(values).boxed();
}
static Fluent of(double[] values) {
requireNonNull(values);
return () -> DoubleStream.of(values).boxed();
}
static Fluent of(long[] values) {
requireNonNull(values);
return () -> LongStream.of(values).boxed();
}
static Fluent of(Iterable values) {
requireNonNull(values);
return (values instanceof Fluent>) ? (Fluent) values : () -> StreamSupport.stream(values.spliterator(), false);
}
static Fluent of(Iterator values) {
requireNonNull(values);
return () -> StreamSupport.stream(Spliterators.spliteratorUnknownSize(values, 0), false);
}
static Fluent of(Stream stream) {
requireNonNull(stream);
return () -> stream;
}
static Fluent ofChars(String text) {
requireNonNull(text);
return of(Stream.generate(new Supplier() {
int index = 0;
@Override
public String get() {
return text.substring(index, ++index);
}
})).limit(text.length());
}
static Fluent split(String text, String regex) {
requireNonNull(text);
requireNonNull(regex);
return of(text.split(regex));
}
public default Fluent map(Function super T, ? extends R> transform) {
requireNonNull(transform);
return () -> stream().map(transform);
}
public default IntStream mapToInt(ToIntFunction super T> transform) {
requireNonNull(transform);
return stream().mapToInt(transform);
}
public default LongStream mapToLong(ToLongFunction super T> transform) {
requireNonNull(transform);
return stream().mapToLong(transform);
}
public default DoubleStream mapToDouble(ToDoubleFunction super T> transform) {
requireNonNull(transform);
return stream().mapToDouble(transform);
}
public default IntStream flatMapToInt(Function super T, ? extends IntStream> transform) {
requireNonNull(transform);
return stream().flatMapToInt(transform);
}
public default LongStream flatMapToLong(Function super T, ? extends LongStream> transform) {
requireNonNull(transform);
return stream().flatMapToLong(transform);
}
public default DoubleStream flatMapToDouble(Function super T, ? extends DoubleStream> transform) {
requireNonNull(transform);
return stream().flatMapToDouble(transform);
}
public default Fluent filter(Predicate super T> predicate) {
requireNonNull(predicate);
return () -> stream().filter(predicate);
}
public default Fluent exclude(Predicate super T> predicate) {
requireNonNull(predicate);
return () -> stream().filter(predicate.negate());
}
@SuppressWarnings("unchecked")
public default Fluent filter(Class type) {
requireNonNull(type);
return (Fluent) filter(value -> type.isInstance(value));
}
public default long size() {
return stream().count();
}
public default long count(Predicate super T> predicate) {
requireNonNull(predicate);
return stream().filter(predicate).count();
}
public default Optional first() {
return stream().findFirst();
}
public default Optional any() {
return stream().findAny();
}
public default Fluent skip(long n) {
return () -> stream().skip(n);
}
public default Optional firstMatch(Predicate super T> predicate) {
requireNonNull(predicate);
return stream().filter(predicate).findFirst();
}
public default Optional last() {
return stream().reduce((l, r) -> r);
}
public default boolean isEmpty() {
return !iterator().hasNext();
}
public default String join(CharSequence delimiter) {
requireNonNull(delimiter);
StringJoiner joiner = new StringJoiner(delimiter);
forEach(value -> joiner.add(String.valueOf(value)));
return joiner.toString();
}
public default String join() {
return join("");
}
public default boolean contains(Object element) {
return stream().anyMatch(Predicate.isEqual(element));
}
public default int indexOf(Object element) {
int index = 0;
for (T value : this) {
if (Objects.equals(value, element)) {
return index;
}
index++;
}
return -1;
}
public default T[] toArray(IntFunction generator) {
requireNonNull(generator);
return stream().toArray(generator);
}
public default List toList() {
return copyInto(new ArrayList<>());
}
public default List toSortedList(Comparator super T> comparator) {
requireNonNull(comparator);
List list = copyInto(new ArrayList<>());
Collections.sort(list, comparator);
return list;
}
public default SortedSet toSortedSet(Comparator super T> comparator) {
requireNonNull(comparator);
return copyInto(new TreeSet<>(comparator));
}
public default Set toSet() {
return copyInto(new HashSet<>());
}
public default boolean anyMatch(Predicate super T> predicate) {
requireNonNull(predicate);
return stream().anyMatch(predicate);
}
public default boolean allMatch(Predicate super T> predicate) {
requireNonNull(predicate);
return stream().allMatch(predicate);
}
public default boolean noneMatch(Predicate super T> predicate) {
requireNonNull(predicate);
return stream().noneMatch(predicate);
}
public default R collect(Collector super T, A, ? extends R> collector) {
requireNonNull(collector);
return stream().collect(collector);
}
public default Fluent limit(int limitSize) {
if (limitSize < 0) {
throw new IllegalArgumentException("limit is negative");
}
return () -> stream().limit(limitSize);
}
public default Fluent cycle() {
return () -> Stream.generate(() -> stream()).flatMap(s -> s);
}
public default void forEachWithIndex(BiConsumer consumer) {
requireNonNull(consumer);
int index = 0;
for (T value : this) {
consumer.accept(index++, value);
}
}
public default Fluent peek(Consumer super T> action) {
requireNonNull(action);
return () -> stream().peek(action);
}
public default void forEachOrdered(Consumer super T> action) {
requireNonNull(action);
stream().forEachOrdered(action);
}
public default Iterator iterator() {
return stream().iterator();
}
public default Spliterator spliterator() {
return stream().spliterator();
}
public default boolean isParallel() {
return stream().isParallel();
}
public default Fluent sequential() {
return () -> stream().sequential();
}
public default Fluent unordered() {
return () -> stream().unordered();
}
public default IntStream intStream(ToIntFunction super T> mapper) {
requireNonNull(mapper);
return stream().mapToInt(mapper);
}
public default LongStream longStream(ToLongFunction super T> mapper) {
requireNonNull(mapper);
return stream().mapToLong(mapper);
}
public default DoubleStream doubleStream(ToDoubleFunction super T> mapper) {
requireNonNull(mapper);
return stream().mapToDouble(mapper);
}
public default Optional min(Comparator super T> comparator) {
requireNonNull(comparator);
return stream().min(comparator);
}
public default Optional max(Comparator super T> comparator) {
requireNonNull(comparator);
return stream().max(comparator);
}
public default > C copyInto(C collection) {
requireNonNull(collection);
return stream().collect(Collectors.toCollection(() -> collection));
}
public default T reduce(T identity, BinaryOperator accumulator) {
requireNonNull(accumulator);
return stream().reduce(identity, accumulator);
}
public default Optional reduce(BinaryOperator accumulator) {
requireNonNull(accumulator);
return stream().reduce(accumulator);
}
public default Map uniqueIndex(Function super T, K> toKey) {
requireNonNull(toKey);
Map map = new HashMap<>();
forEach(value -> {
K key = toKey.apply(value);
if (null != map.put(key, value)) {
throw new IllegalArgumentException("Same key used twice" + key);
}
});
return map;
}
public default Map> index(Function super T, K> toKey) {
requireNonNull(toKey);
Map> multiMap = new HashMap<>();
forEach(value -> {
K key = toKey.apply(value);
List list = multiMap.computeIfAbsent(key, k -> new ArrayList());
list.add(value);
});
return multiMap;
}
public default Map toMap(Function super T, V> toValue) {
requireNonNull(toValue);
Map map = new HashMap<>();
forEach(key -> {
V value = toValue.apply(key);
if (null != map.put(key, value)) {
throw new IllegalArgumentException("Same key used twice" + key);
}
});
return map;
}
public default Map toMap(Function super T, K> toKey, Function super T, V> toValue) {
requireNonNull(toKey);
requireNonNull(toValue);
Map map = new HashMap<>();
forEach(item -> {
K key = toKey.apply(item);
V value = toValue.apply(item);
if (null != map.put(key, value)) {
throw new IllegalArgumentException("Same key used twice" + key);
}
});
return map;
}
public default T get(int index) {
if (index < 0) {
throw new IllegalArgumentException("index is negative");
}
int current = 0;
for (T next : this) {
if (current == index) {
return next;
}
current++;
}
throw new ArrayIndexOutOfBoundsException();
}
public default > Fluent flatMap(Function super T, L> toList) {
requireNonNull(toList);
return () -> {
Function super L, Stream> toStream = l -> l.stream();
Function super T, Stream> toListAndThenToStream = toList.andThen(toStream);
return stream().flatMap(toListAndThenToStream);
};
}
public default Fluent parallel() {
return () -> stream().parallel();
}
public default Fluent sorted() {
return () -> stream().sorted();
}
public default Fluent distinct() {
return () -> stream().distinct();
}
public default Fluent sorted(Comparator super T> comparator) {
requireNonNull(comparator);
return () -> stream().sorted(comparator);
}
public default Fluent reversed(Comparator super T> comparator) {
requireNonNull(comparator);
return () -> stream().sorted(comparator.reversed());
}
public default > Fluent sortedOn(Function super T, C> comparator) {
requireNonNull(comparator);
return () -> stream().sorted((l, r) -> comparator.apply(l).compareTo(comparator.apply(r)));
}
public default > Fluent reversedOn(Function super T, C> comparator) {
requireNonNull(comparator);
return () -> stream().sorted((l, r) -> comparator.apply(r).compareTo(comparator.apply(l)));
}
//@SafeVarargs
public default Fluent concat(T... values) {
requireNonNull(values);
return () -> Stream.concat(stream(), Stream.of(values));
}
public default Fluent concat(Iterable values) {
requireNonNull(values);
return () -> Stream.concat(stream(), StreamSupport.stream(values.spliterator(), false));
}
public default T getOnlyElement() {
return first().get();
}
public default Fluent notNulls() {
return filter(v -> v != null);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy