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

com.artclod.common.collect.base.BaseFColletion Maven / Gradle / Ivy

There is a newer version: 0.0.15
Show newest version
package com.artclod.common.collect.base;

import static com.google.common.base.Preconditions.checkNotNull;

import java.io.Serializable;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Spliterator;
import java.util.function.BiFunction;
import java.util.function.BinaryOperator;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Stream;

import com.artclod.common.collect.ArrayFList;
import com.artclod.common.collect.FCollection;
import com.artclod.common.collect.FList;
import com.artclod.common.collect.builder.CollectionBuilder;
import com.google.common.collect.Maps;

public abstract class BaseFColletion> implements FCollection, Serializable {
	private static final long serialVersionUID = 1L;

	final Collection inner;

	public BaseFColletion(Collection inner) {
		this.inner = checkNotNull(inner);
	}

	/**
	 * Intended for internal use. 
	 * Creates an empty builder that can be used to create a collection of correct type.
	 * 
	 * @return a builder for this collections type
	 */
	protected abstract CollectionBuilder builder();
	
	/**
	 * Best effort to be able to iterator through this collection in reverse.
	 * Not that for collections that do not have a real reverse nothing is guaranteed (i.e. reverse and forward may even be the same).
	 * 
	 * @return an iterator the progresses in reverse order
	 */
	protected abstract Iterator reverseIterator();
	
	// =========== Identity as inner ===========
	public boolean equals(Object o) {
		return inner.equals(o);
	}

	public int hashCode() {
		return inner.hashCode();
	}

	@Override
	public String toString() {
		return inner.toString();
	}

	// ============ FCollection Methods (or support) =========	
	public boolean nonEmpty() {
		return !isEmpty();
	}
	
	public String mkString(String sep) {
		return mkString("", sep, "");
	}

	public String mkString(String start, String sep, String end) {
		StringBuilder ret = new StringBuilder(start);
		Iterator iterator = iterator();
		boolean first = true;
		while (iterator.hasNext()) {
			E e = iterator.next();
			if (first) {
				ret.append(e);
				first = false;
			} else {
				ret.append(sep).append(e);
			}
		}
		return ret.append(end).toString();
	}

	// --- Reduce ---
	public Optional reduce(BinaryOperator accumulator){
		return reduceLeft(accumulator);
	}
	
	public Optional reduceLeft(BinaryOperator accumulator){
		if(isEmpty()) { return Optional.empty(); }
		Iterator iterator = iterator();
		E first = iterator.next();
		return Optional.of(reduceInner(first, accumulator, iterator));
	}
	
	public Optional reduceRight(BinaryOperator accumulator){
		if(isEmpty()) { return Optional.empty(); }
		Iterator iterator = reverseIterator();
		E first = iterator.next();
		return Optional.of(reduceInner(first, accumulator, iterator));
	}
		
	public E reduce(E identity, BinaryOperator accumulator){
		return reduceLeft(identity, accumulator);
	}	
	
	public E reduceLeft(E identity, BinaryOperator accumulator){
		return reduceInner(identity, accumulator, iterator());
	}
	
	public E reduceRight(E identity, BinaryOperator accumulator){
		return reduceInner(identity, accumulator, reverseIterator());
	}
	
	private E reduceInner(E first, BinaryOperator f, Iterator iterator) {
		E ret = first;
		while(iterator.hasNext()) {
			ret = f.apply(ret, iterator.next());
		}
		return ret;
	}

	// --- Fold ---
	public  O fold(O initial, BiFunction f) {
		return foldLeft(initial, f);
	}

	public  O foldLeft(O initial, BiFunction f) {
		return foldInner(initial, f, iterator());
	}

	public  O foldRight(O initial, BiFunction f) {
		return foldInner(initial, f, reverseIterator());
	}

	private  O foldInner(O i, BiFunction f, Iterator iterator) {
		O ret = i;
		while(iterator.hasNext()) {
			ret = f.apply(ret, iterator.next());
		}
		return ret;
	}

	// --- Filter ---
	public C filterNot(Predicate filter) {
		return filter(filter.negate());
	}

	public C filter(Predicate filter) {
		CollectionBuilder ret = builder();
		for(E e: this){
			if(filter.test(e)){
				ret.add(e);
			}
		}
		return ret.build();
	}
	
	// --- Group ---
	public  Map> groupBy(Function f) {
		LinkedHashMap> ret = Maps.newLinkedHashMap();
		for(E e: this) {
			K key = f.apply(e);
			FList fList = ret.get(key);
			if(fList == null) {
				fList = ArrayFList.create();
				ret.put(key, fList);
			}
			fList.add(e);
		}
		return ret;
	}

	
	// ============ DELEGATE METHODS =========
	public void forEach(Consumer action) {
		inner.forEach(action);
	}

	public int size() {
		return inner.size();
	}

	public boolean isEmpty() {
		return inner.isEmpty();
	}

	public boolean contains(Object o) {
		return inner.contains(o);
	}

	public Iterator iterator() {
		return inner.iterator();
	}

	public Object[] toArray() {
		return inner.toArray();
	}

	public  T[] toArray(T[] a) {
		return inner.toArray(a);
	}

	public boolean add(E e) {
		return inner.add(e);
	}

	public boolean remove(Object o) {
		return inner.remove(o);
	}

	public boolean containsAll(Collection c) {
		return inner.containsAll(c);
	}

	public boolean addAll(Collection c) {
		return inner.addAll(c);
	}

	public boolean removeAll(Collection c) {
		return inner.removeAll(c);
	}

	public boolean retainAll(Collection c) {
		return inner.retainAll(c);
	}
	public boolean removeIf(Predicate filter) {
		return inner.removeIf(filter);
	}

	public void clear() {
		inner.clear();
	}

	public Stream stream() {
		return inner.stream();
	}

	public Stream parallelStream() {
		return inner.parallelStream();
	}

	public Spliterator spliterator() {
		return inner.spliterator();
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy