Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.rx.core.NQuery Maven / Gradle / Ivy
package org.rx.core;
import com.google.common.collect.Streams;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import org.apache.commons.collections4.IterableUtils;
import org.apache.commons.collections4.IteratorUtils;
import org.rx.annotation.ErrorCode;
import org.rx.beans.Tuple;
import java.io.Serializable;
import java.lang.reflect.Array;
import java.util.*;
import java.util.Collections;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import static org.rx.core.Contract.*;
/**
* https://msdn.microsoft.com/en-us/library/bb738550(v=vs.110).aspx
*
* @param
*/
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public final class NQuery implements Iterable, Serializable {
//region nestedTypes
@FunctionalInterface
public interface IndexSelector {
TR apply(T t, int index);
}
@FunctionalInterface
public interface IndexPredicate {
boolean test(T t, int index);
default IndexPredicate negate() {
return (t, i) -> !test(t, i);
}
}
//endregion
//region staticMembers
@SuppressWarnings(NonWarning)
@ErrorCode(value = "argError", messageKeys = {"$type"})
public static List asList(Object arrayOrIterable) {
require(arrayOrIterable);
Class type = arrayOrIterable.getClass();
if (type.isArray()) {
int length = Array.getLength(arrayOrIterable);
List list = new ArrayList<>(length);
for (int i = 0; i < length; i++) {
Object item = Array.get(arrayOrIterable, i);
list.add((T) item);
}
return list;
}
Iterable iterable;
if ((iterable = as(arrayOrIterable, Iterable.class)) != null) {
return toList(iterable);
}
throw new SystemException(values(type.getSimpleName()), "argError");
}
public static List toList(Iterable iterable) {
return IterableUtils.toList(iterable);
}
public static List toList(Iterator iterator) {
return IteratorUtils.toList(iterator);
}
public static NQuery of(T one) {
return of(Arrays.toList(one));
}
@SafeVarargs
public static NQuery of(T... set) {
return of(Arrays.toList(set));
}
public static NQuery of(Iterable iterable) {
return of(iterable.iterator());
}
public static NQuery of(Iterator iterator) {
return of(toList(iterator));
}
public static NQuery of(Stream stream) {
require(stream);
return of(stream.collect(Collectors.toList()), stream.isParallel());
}
public static NQuery of(Collection set) {
return of(set, false);
}
public static NQuery of(Collection set, boolean isParallel) {
require(set);
return new NQuery<>(set, isParallel);
}
//endregion
//region Member
private Collection current;
private boolean isParallel;
public Stream stream() {
return isParallel ? current.parallelStream() : current.stream();
}
@Override
public Iterator iterator() {
return stream().iterator();
}
private List newList() {
int count = count();
return isParallel ? new Vector<>(count) : new ArrayList<>(count);//CopyOnWriteArrayList 写性能差
}
private Set newSet() {
int count = count();
return isParallel ? Collections.synchronizedSet(new LinkedHashSet<>(count)) : new LinkedHashSet<>(count);
}
private Map newMap() {
int count = count();
return isParallel ? Collections.synchronizedMap(new LinkedHashMap<>(count)) : new LinkedHashMap<>(count);
}
private Stream newStream(Collection set) {
return isParallel ? set.parallelStream() : set.stream();
}
private NQuery me(Collection set) {
return of(set, isParallel);
}
private NQuery me(Stream stream) {
return me(stream.collect(Collectors.toList()));
}
private NQuery me(EachFunc func) {
return me(stream(), func);
}
private NQuery me(Stream stream, EachFunc func) {
boolean isParallel = stream.isParallel();
Spliterator spliterator = stream.spliterator();
return me(StreamSupport.stream(new Spliterators.AbstractSpliterator (spliterator.estimateSize(), spliterator.characteristics()) {
AtomicBoolean breaker = new AtomicBoolean();
AtomicInteger counter = new AtomicInteger();
@SuppressWarnings(NonWarning)
@Override
public boolean tryAdvance(Consumer action) {
return spliterator.tryAdvance(p -> {
int flags = func.each(p, counter.getAndIncrement());
if ((flags & EachFunc.Accept) == EachFunc.Accept) {
action.accept(p);
}
if ((flags & EachFunc.Break) == EachFunc.Break) {
breaker.set(true);
}
}) && !breaker.get();
}
}, isParallel));
}
@FunctionalInterface
private interface EachFunc {
int None = 0;
int Accept = 1;
int Break = 1 << 1;
int All = Accept | Break;
int each(T t, int index);
}
//endregion
public NQuery each(IndexPredicate func) {
Iterator tor = this.iterator();
int i = 0;
while (tor.hasNext()) {
if (!func.test(tor.next(), i++)) {
break;
}
}
return this;
}
public NQuery select(Function selector) {
return me(stream().map(selector));
}
public NQuery select(IndexSelector selector) {
AtomicInteger counter = new AtomicInteger();
return me(stream().map(p -> selector.apply(p, counter.getAndIncrement())));
}
public NQuery selectMany(Function> selector) {
return me(stream().flatMap(p -> newStream(selector.apply(p))));
}
public NQuery selectMany(IndexSelector> selector) {
AtomicInteger counter = new AtomicInteger();
return me(stream().flatMap(p -> newStream(selector.apply(p, counter.getAndIncrement()))));
}
public NQuery where(Predicate predicate) {
return me(stream().filter(predicate));
}
public NQuery where(IndexPredicate predicate) {
AtomicInteger counter = new AtomicInteger();
return me(stream().filter(p -> predicate.test(p, counter.getAndIncrement())));
}
public NQuery join(Collection inner, BiPredicate keySelector, BiFunction resultSelector) {
return me(stream().flatMap(p -> newStream(inner).filter(p2 -> keySelector.test(p, p2)).map(p3 -> resultSelector.apply(p, p3))));
}
public NQuery join(Function innerSelector, BiPredicate keySelector, BiFunction resultSelector) {
return join(stream().map(innerSelector).collect(Collectors.toList()), keySelector, resultSelector);
}
public NQuery joinMany(Function> innerSelector, BiPredicate keySelector, BiFunction resultSelector) {
return join(stream().flatMap(p -> newStream(innerSelector.apply(p))).collect(Collectors.toList()), keySelector, resultSelector);
}
@SuppressWarnings(NonWarning)
public NQuery leftJoin(Collection inner, BiPredicate keySelector, BiFunction resultSelector) {
return me(stream().flatMap(p -> {
if (!newStream(inner).anyMatch(p2 -> keySelector.test(p, p2))) {
return Stream.of(resultSelector.apply(p, null));
}
return newStream(inner).filter(p2 -> keySelector.test(p, p2)).map(p3 -> resultSelector.apply(p, p3));
}));
}
public NQuery leftJoin(Function innerSelector, BiPredicate keySelector, BiFunction resultSelector) {
return leftJoin(stream().map(innerSelector).collect(Collectors.toList()), keySelector, resultSelector);
}
public NQuery leftJoinMany(Function> innerSelector, BiPredicate keySelector, BiFunction resultSelector) {
return leftJoin(stream().flatMap(p -> newStream(innerSelector.apply(p))).collect(Collectors.toList()), keySelector, resultSelector);
}
public boolean all(Predicate predicate) {
return stream().allMatch(predicate);
}
public boolean any() {
return stream().findAny().isPresent();
}
public boolean any(Predicate predicate) {
return stream().anyMatch(predicate);
}
public boolean contains(T item) {
return stream().anyMatch(p -> p.equals(item));
}
public NQuery concat(Iterable set) {
return concat(toList(set));
}
public NQuery concat(Collection set) {
return me(Stream.concat(stream(), newStream(set)));
}
public NQuery distinct() {
return me(stream().distinct());
}
public NQuery except(Iterable set) {
return except(toList(set));
}
@SuppressWarnings(NonWarning)
public NQuery except(Collection set) {
return me(stream().filter(p -> !newStream(set).anyMatch(p2 -> p2.equals(p))));
}
public NQuery intersect(Iterable set) {
return intersect(toList(set));
}
public NQuery intersect(Collection set) {
return me(stream().filter(p -> newStream(set).anyMatch(p2 -> p2.equals(p))));
}
public NQuery union(Iterable set) {
return union(toList(set));
}
public NQuery union(Collection set) {
return concat(set);
}
public NQuery orderBy(Function keySelector) {
return me(stream().sorted(getComparator(keySelector)));
}
@SuppressWarnings(NonWarning)
public static Comparator getComparator(Function keySelector) {
return (p1, p2) -> {
Comparable c1 = as(keySelector.apply(p1), Comparable.class);
Comparable c2 = as(keySelector.apply(p2), Comparable.class);
if (c1 == null || c2 == null) {
return 0;
}
return c1.compareTo(c2);
};
}
public NQuery orderByDescending(Function keySelector) {
return me(stream().sorted(getComparator(keySelector).reversed()));
}
public NQuery orderByMany(Function keySelector) {
return me(stream().sorted(getComparatorMany(keySelector)));
}
@SuppressWarnings(NonWarning)
public static Comparator getComparatorMany(Function keySelector) {
return (p1, p2) -> {
Object[] k1s = keySelector.apply(p1);
Object[] k2s = keySelector.apply(p2);
for (int i = 0; i < k1s.length; i++) {
Comparable c1 = as(k1s[i], Comparable.class);
Comparable c2 = as(k2s[i], Comparable.class);
if (c1 == null || c2 == null) {
continue;
}
int r = c1.compareTo(c2);
if (r == 0) {
continue;
}
return r;
}
return 0;
};
}
public NQuery orderByDescendingMany(Function keySelector) {
return me(stream().sorted(getComparatorMany(keySelector).reversed()));
}
@SuppressWarnings(NonWarning)
public NQuery reverse() {
return me(stream().sorted((Comparator) Comparator.reverseOrder()));
}
public NQuery groupBy(Function keySelector, BiFunction, TR> resultSelector) {
Map> map = newMap();
stream().forEach(t -> map.computeIfAbsent(keySelector.apply(t), p -> newList()).add(t));
List result = newList();
for (Map.Entry> entry : map.entrySet()) {
result.add(resultSelector.apply(entry.getKey(), of(entry.getValue())));
}
return me(result);
}
public NQuery groupByMany(Function keySelector, BiFunction, TR> resultSelector) {
Map>> map = newMap();
stream().forEach(t -> {
Object[] ks = keySelector.apply(t);
map.computeIfAbsent(toJsonString(ks), p -> Tuple.of(ks, newList())).right.add(t);
});
List result = newList();
for (Tuple> entry : map.values()) {
result.add(resultSelector.apply(entry.left, of(entry.right)));
}
return me(result);
}
public Double average(ToDoubleFunction selector) {
OptionalDouble q = stream().mapToDouble(selector).average();
return q.isPresent() ? q.getAsDouble() : null;
}
public int count() {
return current.size();
}
public int count(Predicate predicate) {
return (int) stream().filter(predicate).count();
}
public T max() {
return max(stream());
}
@SuppressWarnings(NonWarning)
private TR max(Stream stream) {
return stream.max((Comparator ) Comparator.naturalOrder()).orElse(null);
}
public TR max(Function selector) {
return max(stream().map(selector));
}
public T min() {
return min(stream());
}
@SuppressWarnings(NonWarning)
private TR min(Stream stream) {
return stream.min((Comparator ) Comparator.naturalOrder()).orElse(null);
}
public TR min(Function selector) {
return min(stream().map(selector));
}
public double sum(ToDoubleFunction selector) {
return stream().mapToDouble(selector).sum();
}
@SuppressWarnings(NonWarning)
public NQuery cast() {
return (NQuery ) this;
}
@SuppressWarnings(NonWarning)
public NQuery ofType(Class type) {
return where(p -> Reflects.isInstance(p, type)).select(p -> (TR) p);
}
@SuppressWarnings(NonWarning)
public T first() {
return stream().findFirst().get();
}
public T first(Predicate predicate) {
return where(predicate).first();
}
public T firstOrDefault() {
return firstOrDefault((T) null);
}
public T firstOrDefault(T defaultValue) {
return stream().findFirst().orElse(defaultValue);
}
public T firstOrDefault(Predicate predicate) {
return where(predicate).firstOrDefault();
}
@SuppressWarnings(NonWarning)
public T last() {
return Streams.findLast(stream()).get();
}
public T last(Predicate predicate) {
return where(predicate).last();
}
public T lastOrDefault() {
return lastOrDefault((T) null);
}
public T lastOrDefault(T defaultValue) {
return Streams.findLast(stream()).orElse(defaultValue);
}
public T lastOrDefault(Predicate predicate) {
return where(predicate).lastOrDefault();
}
@ErrorCode(messageKeys = {"$count"})
public T single() {
int count = count();
if (count != 1) {
throw new SystemException(values(count));
}
return first();
}
public T single(Predicate predicate) {
return where(predicate).single();
}
@ErrorCode(messageKeys = {"$count"})
public T singleOrDefault() {
int count = count();
if (count > 1) {
throw new SystemException(values(count));
}
return firstOrDefault();
}
public T singleOrDefault(Predicate predicate) {
return where(predicate).singleOrDefault();
}
public NQuery skip(int count) {
return me(stream().skip(count));
}
public NQuery skipWhile(Predicate predicate) {
return skipWhile((p, i) -> predicate.test(p));
}
public NQuery skipWhile(IndexPredicate predicate) {
AtomicBoolean doAccept = new AtomicBoolean();
return me((p, i) -> {
int flags = EachFunc.None;
if (doAccept.get()) {
flags |= EachFunc.Accept;
return flags;
}
if (!predicate.test(p, i)) {
doAccept.set(true);
flags |= EachFunc.Accept;
}
return flags;
});
}
public NQuery take(int count) {
return me(stream().limit(count));
}
public NQuery takeWhile(Predicate predicate) {
return takeWhile((p, i) -> predicate.test(p));
}
public NQuery takeWhile(IndexPredicate predicate) {
return me((p, i) -> {
int flags = EachFunc.None;
if (!predicate.test(p, i)) {
flags |= EachFunc.Break;
return flags;
}
flags |= EachFunc.Accept;
return flags;
});
}
public Collection asCollection() {
return current;
}
public String toJoinString(String delimiter, Function selector) {
return String.join(delimiter, select(selector));
}
@SuppressWarnings(NonWarning)
public T[] toArray() {
List result = toList();
Class type = null;
for (T t : result) {
if (t == null) {
continue;
}
type = t.getClass();
break;
}
if (type == null) {
throw new InvalidOperationException("Empty Result");
}
T[] array = (T[]) Array.newInstance(type, result.size());
result.toArray(array);
return array;
}
@SuppressWarnings(NonWarning)
public T[] toArray(Class type) {
List result = toList();
T[] array = (T[]) Array.newInstance(type, result.size());
result.toArray(array);
return array;
}
public List toList() {
List result = newList();
result.addAll(current);
return result;
}
public Set toSet() {
Set result = newSet();
result.addAll(current);
return result;
}
public Map toMap(Function keySelector) {
return toMap(keySelector, p -> p);
}
//Collectors.toMap 会校验value为null的情况
public Map toMap(Function keySelector, Function resultSelector) {
Map result = newMap();
for (T item : current) {
result.put(keySelector.apply(item), resultSelector.apply(item));
}
return result;
}
}