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

no.motif.iter.CollectingIterable Maven / Gradle / Ivy

package no.motif.iter;

import static java.util.Collections.sort;
import static java.util.Collections.unmodifiableList;
import static no.motif.Base.toString;
import static no.motif.Iterate.by;
import static no.motif.Singular.optional;
import static no.motif.Strings.concat;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import no.motif.Singular;
import no.motif.Strings;
import no.motif.f.Do;
import no.motif.f.Fn;
import no.motif.f.Fn2;
import no.motif.f.Predicate;
import no.motif.single.Optional;
import no.motif.types.Elements;

/**
 * This iterable offers operations which requires collecting (i.e.
 * iterating) the containing elements of the iterable. In
 * particular, this class holds the methods which "bridges" back
 * to the non-lazy Java Collection Framework classes.
 *
 * @param  The type of elements in this iterable.
 */
abstract class CollectingIterable implements Elements, Serializable {

    @Override
    public final  O reduce(O unit, Fn2 reducer) {
        O reduced = unit;
        for (T element : this) reduced = reducer.$(reduced, element);
        return reduced;
    }


    @Override
    public final List collect() {
        return unmodifiableList(collectIn(new ArrayList()));
    }


    @Override
    public final > C collectIn(C collection) {
        for (T t : this) {
            collection.add(t);
        }
        return collection;
    }



    @Override
    public final 

> List sortedBy(Fn property) { return sorted(by(property)); } @Override public final List sorted(Comparator comparator) { List elements = collectIn(new ArrayList()); sort(elements, comparator); return unmodifiableList(elements); } @Override public void each(Do sideEffect) { for (T element : this) sideEffect.with(element); } @Override public

Map> groupBy(Fn property) { Map> map = new LinkedHashMap<>(); for (T elem : this) { P key = property.$(elem); List list; if (!map.containsKey(key)) { list = new ArrayList<>(); map.put(key, list); } else { list = map.get(key); } list.add(elem); } return map; } @Override public

Map mapBy(Fn uniqueProperty) { Map map = new LinkedHashMap<>(); for (T elem : this) { P key = uniqueProperty.$(elem); if (!map.containsKey(key)) map.put(key, elem); else throw new IllegalStateException( "Cannot create the map since both '" + map.get(key) + "' and '" + elem + "' yields " + "the same key: '" + key + "'. This is either due to an inconsistency in " + "your data, or you should use .groupBy(Fn) instead to allow multiple elements " + "being mapped by the same key."); } return map; } @Override public boolean isEmpty() { return !iterator().hasNext(); } @Override public boolean exists(Predicate predicate) { for (T t : this) if (predicate.$(t)) return true; return false; } @Override public Optional head() { return !isEmpty() ? optional(iterator().next()) : Singular.none(); } @Override public Optional last() { T last = null; for (T elem : this) last = elem; return optional(last); } @Override public String join() { return reduce("", concat); } @Override public String join(String separator) { if (isEmpty()) return ""; return head().map(toString).append(tail().map(Strings.prepend(separator))).reduce("", concat); } /** * Textual description of the contents of the iterable. Have in mind that for lazy * implementations, using {@link #toString()} will iterate over the elements to * actually be able to create the description. */ @Override public String toString() { return collect().toString(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy