All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.xyzwps.lib.dollar.Seq Maven / Gradle / Ivy

The newest version!
package com.xyzwps.lib.dollar;


import com.xyzwps.lib.dollar.function.ObjIntFunction;
import com.xyzwps.lib.dollar.function.ObjIntPredicate;

import java.util.*;
import java.util.function.*;

import static com.xyzwps.lib.dollar.Dollar.*;
import static com.xyzwps.lib.dollar.Helper.*;

/**
 * 操作符应该分 3 类
 * 1. 收集一个就可以干活,比如 map、filter
 * 2. 收集一些才能干活,比如 chunk
 * 3. 收集全部才能干活,比如 groupBy、orderBy、reverse
 * 

* TODO: 实现 index 版本 * * @param */ public interface Seq extends Iterable { void forEach(Consumer consumer); default void forEach(ObjIntConsumer consumer) { Objects.requireNonNull(consumer); Counter counter = new Counter(0); this.forEach(t -> consumer.accept(t, counter.getAndIncr())); } default Seq map(Function mapFn) { Objects.requireNonNull(mapFn); return rConsumer -> this.forEach(t -> rConsumer.accept(mapFn.apply(t))); } default Seq map(ObjIntFunction mapFn) { Objects.requireNonNull(mapFn); Counter counter = new Counter(0); return rConsumer -> this.forEach(t -> rConsumer.accept(mapFn.apply(t, counter.getAndIncr()))); } default Seq filter(Predicate predicate) { Objects.requireNonNull(predicate); return tConsumer -> this.forEach(t -> { if (predicate.test(t)) { tConsumer.accept(t); } }); } default Seq filter(ObjIntPredicate predicate) { Objects.requireNonNull(predicate); Counter counter = new Counter(0); return tConsumer -> this.forEach(t -> { if (predicate.test(t, counter.getAndIncr())) { tConsumer.accept(t); } }); } default Seq flatMap(Function> flatMapFn) { return rConsumer -> this.forEach(t -> { Seq rSeq = flatMapFn.apply(t); if (rSeq != null) { rSeq.forEach(rConsumer); } }); } default Seq> chunk(final int chunkSize) { if (chunkSize < 1) { throw new IllegalArgumentException("Each chunk should have at least one element."); } // TODO: 优化 class ChunkEnv { List list = new ArrayList<>(chunkSize); int count = 0; boolean add(T t) { this.list.add(t); this.count++; return this.count == chunkSize; } List getAndClean() { List result = this.list; this.list = new ArrayList<>(chunkSize); this.count = 0; return result; } } return listConsumer -> { ChunkEnv env = new ChunkEnv(); this.forEach(t -> { if (env.add(t)) { listConsumer.accept(env.getAndClean()); } }); if (env.count > 0) { listConsumer.accept(env.getAndClean()); } }; } default Seq compact() { return this.filter(t -> !$.isFalsey(t)); } default Seq concat(Iterable seq2) { if (seq2 == null) return this; return tConsumer -> { this.forEach(tConsumer); seq2.forEach(tConsumer); }; } default Seq take(final int n) { if (n < 1) { throw new IllegalArgumentException("You should take at least one element."); } return StopException.stop(tConsumer -> { Counter counter = new Counter(0); this.forEach(t -> { if (counter.getAndIncr() < n) { tConsumer.accept(t); } if (counter.get() >= n) { throw new StopException(); } }); }); } default Seq takeWhile(Predicate predicate) { Objects.requireNonNull(predicate); return StopException.stop(tConsumer -> { this.forEach(t -> { if (predicate.test(t)) { tConsumer.accept(t); } else { throw new StopException(); } }); }); } default Seq skip(int n) { return tConsumer -> { int[] counter = {0}; this.forEach(t -> { if (counter[0] < n) { counter[0]++; } else { tConsumer.accept(t); } }); }; } default Seq skipWhile(Predicate predicate) { return tConsumer -> { boolean[] next = {true}; this.forEach(t -> { next[0] = next[0] && predicate.test(t); if (!next[0]) { tConsumer.accept(t); } }); }; } default Optional first() { Holder holder = new Holder<>(null); StopException.stop(() -> this.forEach(t -> { holder.value = t; throw new StopException(); })); return Optional.ofNullable(holder.value); } default Optional head() { return this.first(); } default R reduce(R initValue, BiFunction reducer) { Holder rHolder = new Holder<>(initValue); this.forEach(t -> rHolder.value = reducer.apply(rHolder.value, t)); return rHolder.value; } default Seq reverse() { ArrayList list = this.toList(); ArrayListReverseIterator itr = new ArrayListReverseIterator<>(list); return tConsumer -> { while (itr.hasNext()) tConsumer.accept(itr.next()); }; } @Override default Iterator iterator() { List list = this.toList(); return list.iterator(); } default > Seq orderBy(Function toKey, Direction direction) { Objects.requireNonNull(toKey); Objects.requireNonNull(direction); ArrayList list = this.toList(); Comparator comparator = direction == Direction.DESC ? descComparator(toKey) : ascComparator(toKey); list.sort(comparator); return list::forEach; } default Seq zip(Iterable iterable, BiFunction zipper) { Objects.requireNonNull(zipper); if (iterable == null) { return this.map(t -> zipper.apply(t, null)); } Iterator itr = iterable.iterator(); return rConsumer -> { this.forEach(t -> rConsumer.accept(zipper.apply(t, itr.hasNext() ? itr.next() : null))); while (itr.hasNext()) { rConsumer.accept(zipper.apply(null, itr.next())); } }; } default Seq> zip(Iterable iterable) { return this.zip(iterable, Pair::of); } default MESeq> groupBy(Function toKey) { Objects.requireNonNull(toKey); Map> map = new HashMap<>(); this.forEach(t -> map.computeIfAbsent(toKey.apply(t), k -> new ArrayList<>()).add(t)); return map::forEach; } default MESeq keyBy(Function toKey) { Objects.requireNonNull(toKey); Map map = new HashMap<>(); this.forEach(t -> map.computeIfAbsent(toKey.apply(t), k -> t)); return map::forEach; } default Seq uniqueBy(Function toKey) { Objects.requireNonNull(toKey); Set set = new HashSet<>(); return tConsumer -> { this.forEach(t -> { K key = toKey.apply(t); if (set.contains(key)) { return; } set.add(key); tConsumer.accept(t); }); }; } default Seq unique() { Set set = new HashSet<>(); return tConsumer -> { this.forEach(t -> { if (set.contains(t)) { return; } set.add(t); tConsumer.accept(t); }); }; } default String join(String sep) { // TODO: 检查 seq return this.reduce(new StringJoiner(sep), (joiner, t) -> { joiner.add(t == null ? null : t.toString()); return joiner; }).toString(); } default HashSet toSet() { return this.reduce(new HashSet<>(), (set, t) -> { set.add(t); return set; }); } default ArrayList toList() { return this.reduce(new ArrayList<>(), (list, t) -> { list.add(t); return list; }); } static Seq empty() { return tConsumer -> { }; } default List value() { return this.toList(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy