Algorithms.java :  » Algebra » symja » org » matheclipse » generic » Java Open Source

Java Open Source » Algebra » symja 
symja » org » matheclipse » generic » Algorithms.java
package org.matheclipse.generic;

import java.util.Collection;
import java.util.List;

import org.matheclipse.generic.interfaces.BiFunction;
import org.matheclipse.generic.interfaces.ISequence;

import com.google.common.base.Function;
import com.google.common.base.Predicate;

/**
 * Functional Programming algorithms for <code>java.util.List</code> and
 * <code>java.util.Collection</code>.
 * 
 * @see org.matheclipse.generic.nested.NestedAlgorithms NestedAlgorithms for
 *      nested lists algorithms
 */
public class Algorithms {

  /**
   * Return the number of elements in the collection that equals the given
   * value.
   */
  public static <T> int count(final Collection<T> collection, final T value) {
    int counter = 0;
    for (final T obj : collection) {

      if (obj.equals(value)) {
        counter++;
      }
    }
    return counter;
  }

  /**
   * Return the number of elements in the <code>list</code> that match the
   * given predicate.
   */
  public static <T> int count(final List<T> list, final int start, final int end, final Predicate<T> fn) {
    int counter = 0;
    for (int i = start; i < end; i++) {

      if (fn.apply(list.get(i))) {
        counter++;
      }
    }
    return counter;
  }

  /**
   * Return the number of elements in the <code>list</code> that equals the
   * given value.
   */
  public static <T> int count(final List<T> list, final int start, final int end, final T value) {
    int counter = 0;
    for (int i = start; i < end; i++) {

      if (list.get(i).equals(value)) {
        counter++;
      }
    }
    return counter;
  }

  /**
   * Returns the number of elements in the collection that match the given
   * predicate.
   */
  public static <T> int countIf(final Collection<T> collection, final Predicate<T> predicate) {
    int counter = 0;
    for (final T obj : collection) {
      if (predicate.apply(obj)) {
        counter++;
      }
    }
    return counter;
  }

  /**
   * Returns the number of elements in the collection that doesn't match the
   * given predicate.
   */
  public static <T> int countIfNot(final Collection<T> collection, final Predicate<T> predicate) {
    int counter = 0;
    for (final T obj : collection) {
      if (!predicate.apply(obj)) {
        counter++;
      }
    }
    return counter;
  }

  /**
   * Drop (remove) the list elements according to the
   * <code>sequenceSpecification</code> for the list indexes.
   * 
   * @param <T>
   * @param list
   * @param resultList
   * @param sequenceSpecification
   */
  public static <T> List<? extends T> drop(final List<? extends T> resultList, final ISequence sequenceSpecification) {
    sequenceSpecification.setListSize(resultList.size());
    int j = sequenceSpecification.getStart();
    for (int i = j; i < sequenceSpecification.getEnd(); i += sequenceSpecification.getStep()) {
      resultList.remove(j);
      j += sequenceSpecification.getStep() - 1;
    }
    return resultList;
  }

  /**
   * Fold the list from lowest to highest index. If the <i>binaryFunction</i>
   * returns <code>null</code>, the left element will be added to the result
   * list, otherwise the result will be <i>folded</i> again with the next
   * element in the list.
   * 
   * @param <T>
   * @param list
   * @param binaryFunction
   * @param resultList
   */
  public static <T> Collection<? super T> foldLeft(final T expr, final List<T> list,
      final BiFunction<T, T, ? extends T> binaryFunction, final Collection<? super T> resultList) {
    return Algorithms.foldLeft(expr, list, 0, list.size(), binaryFunction, resultList);
  }

  /**
   * Fold the list from <code>start</code> index including to <code>end</code>
   * index excluding into the <code>resultCollection</code>. If the
   * <i>binaryFunction</i> returns <code>null</code>, the left element will
   * be added to the result list, otherwise the result will be <i>folded</i>
   * again with the next element in the list.
   * 
   * @param <T>
   * @param list
   * @param start
   * @param end
   * @param binaryFunction
   * @param resultCollection
   */
  public static <T> Collection<? super T> foldLeft(final T expr, final List<T> list, final int start, final int end,
      final BiFunction<T, T, ? extends T> binaryFunction, final Collection<? super T> resultCollection) {
    if (start < end) {
      T elem = expr;
      resultCollection.add(elem);
      for (int i = start; i < end; i++) {

        elem = binaryFunction.apply(elem, list.get(i));
        resultCollection.add(elem);
      }

    }
    return resultCollection;
  }

  /**
   * ForEach applies the unary <code>function</code> to each element in the
   * <code>iterable</code>.
   * 
   * @param <T>
   * @param iterable
   * @param function
   */
  public static <T> void forEach(final Iterable<? extends T> iterable, final Function<T, ? extends T> function) {
    for (T t : iterable) {
      function.apply(t);
    }
  }

  /**
   * ForEach applies the unary <code>function</code> to each element in the
   * <code>list</code> in the range <code>[start .. list.size()[</code>.
   * 
   * @param <T>
   * @param list
   * @param start
   * @param function
   */
  public static <T> void forEach(final List<? extends T> list, int start, final Function<T, ? extends T> function) {
    forEach(list, start, list.size(), function);
  }

  /**
   * ForEach applies the unary <code>function</code> to each element in the
   * <code>list</code> in the range <code>[start .. end[</code>.
   * 
   * @param <T>
   * @param list
   * @param start
   * @param end
   * @param function
   */
  public static <T> void forEach(final List<? extends T> list, int start, int end, final Function<T, ? extends T> function) {
    int len = end < list.size() ? end : list.size();
    for (int i = start; i < len; i++) {
      function.apply(list.get(i));
    }
  }

  /**
   * Return a new expression by folding <code>expr</code> n times
   * 
   * @param <T>
   * @param expr
   * @param n
   * @param cloneList
   */
  public static <T> T nest(final T expr, final int n, final Function<T, ? extends T> fn) {
    T temp = expr;
    for (int i = 0; i < n; i++) {
      temp = fn.apply(temp);
    }
    return temp;
  }

  /**
   * Return a resultList by folding <code>expr</code> n times
   * 
   * @param <T>
   * @param expr
   * @param n
   * @param cloneList
   * @param resultList
   */
  public static <T> void nestList(final T expr, final int n, final Function<T, ? extends T> fn, final Collection<T> resultList) {
    T temp = expr;
    resultList.add(temp);
    for (int i = 0; i < n; i++) {
      temp = fn.apply(temp);
      resultList.add(temp);
    }
  }

  /**
   * Add the list elements to the <code>resultCollection</code> according to
   * the <code>sequenceSpecification</code> for the list indexes.
   * 
   * @param <T>
   * @param list
   * @param resultCollection
   * @param sequenceSpecification
   */
  public static <T> Collection<? super T> take(final List<? extends T> list, final Collection<? super T> resultCollection,
      final ISequence sequenceSpecification) {
    sequenceSpecification.setListSize(list.size());
    for (int i = sequenceSpecification.getStart(); i < sequenceSpecification.getEnd(); i += sequenceSpecification.getStep()) {
      resultCollection.add(list.get(i));
    }
    return resultCollection;
  }

  /**
   * Transform applies the unary <code>function</code> to each element in the
   * <code>iterable</code>. The return value of the <code>function</code>
   * is appended to the <code>resultCollection</code>.
   * 
   * @param <T>
   * @param iterable
   * @param function
   * @param resultCollection
   * @return
   */
  public static <T> Collection<T> transform(final Iterable<T> iterable, final Function<T, ? extends T> function,
      final Collection<T> resultCollection) {
    for (T t : iterable) {
      resultCollection.add(function.apply(t));
    }
    return resultCollection;
  }

  /**
   * Transform applies the unary <code>function</code> to each element in the
   * <code>list</code> in the range <code>[start .. list.size()[</code>.
   * The return value of the <code>function</code> is appended to the
   * <code>resultCollection</code>.
   * 
   * @param <T>
   * @param list
   * @param start
   * @param function
   * @param resultCollection
   * 
   * @return the given resultCollection
   */
  public static <T> Collection<T> transform(final List<T> list, int start, final Function<T, ? extends T> function,
      final Collection<T> resultCollection) {
    return transform(list, start, list.size(), function, resultCollection);
  }

  /**
   * Transform applies the unary <code>function</code> to each element in the
   * <code>list</code> in the range <code>[start .. end[</code>. The return
   * value of the <code>function</code> is appended to the
   * <code>resultCollection</code>.
   * 
   * @param <T>
   * @param list
   * @param start
   * @param end
   * @param function
   * @param resultCollection
   * 
   * @return the given resultCollection
   */
  public static <T> Collection<T> transform(final List<T> list, int start, int end, final Function<T, ? extends T> function,
      final Collection<T> resultCollection) {
    int len = end < list.size() ? end : list.size();
    for (int i = start; i < len; i++) {
      resultCollection.add(function.apply(list.get(i)));
    }
    return resultCollection;
  }

}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.