[ERA-CVS] src/org/jdaemon/util/functional SumFunction.java, NONE, 1.1 SumAccumulator.java, NONE, 1.
Brought to you by:
jessex
Update of /cvsroot/era/src/org/jdaemon/util/functional In directory sc8-pr-cvs17.sourceforge.net:/tmp/cvs-serv24090 Modified Files: Operations.java Accumulator.java Added Files: SumFunction.java SumAccumulator.java UnaryFunction.java BinaryFunction.java MinFunction.java FunctionAccumulator.java MaxFunction.java CountFunction.java Removed Files: Sum.java Unary.java Max.java Count.java Binary.java Min.java Log Message: Generics functional module a la STL - first commit, a little ropey but apparently functional (ha, ha) --- NEW FILE: SumFunction.java --- package org.jdaemon.util.functional; public class SumFunction<T extends Number> implements BinaryFunction<Number, T, Number> { public Number operate(Number a, T b) { // bit of a bugger that there's no way to optimize this! // really this should implement BinaryFunction<T,T,T> and do Integer, Float, Long, or Double // arithmetic depending on the type of T; oh well. Screw type erasure, anyway. if (a == null) a = new Double(0); if (b == null) return a; return new Double(a.doubleValue() + b.doubleValue()); } } --- NEW FILE: SumAccumulator.java --- package org.jdaemon.util.functional; public class SumAccumulator<T extends Number> implements Accumulator<T, Double> { double sum; public void accumulate(T b) { if (b != null) sum += b.doubleValue(); } public Double getResult() { return sum; } } --- NEW FILE: UnaryFunction.java --- package org.jdaemon.util.functional; public interface UnaryFunction<A, R> { R operate(A a); } --- NEW FILE: BinaryFunction.java --- package org.jdaemon.util.functional; public interface BinaryFunction<A, B, R> { R operate(A a, B b); } --- NEW FILE: MinFunction.java --- package org.jdaemon.util.functional; import java.util.Comparator; public class MinFunction<T> implements BinaryFunction<T, T, T> { private final Comparator<T> comparator; public MinFunction(Comparator<T> comp) { super(); this.comparator = comp; } /** compare a,b * * Note special semantics: * * if a = null, min(a,b) = b; * if b = null, min(a,b) = a; * * @param a * @param b * @return */ public T operate(T a, T b) { if (a == null) return b; if (b == null) return a; return comparator.compare(a, b) < 0 ? a : b; } } --- NEW FILE: FunctionAccumulator.java --- package org.jdaemon.util.functional; public class FunctionAccumulator<T, R> implements Accumulator<T,R> { private R accumulator; private final BinaryFunction<R, T, R> fn; public FunctionAccumulator(R a, final BinaryFunction<R, T, R> f) { super(); accumulator = a; fn = f; } public void accumulate(T t) { accumulator = fn.operate(accumulator, t); } public R getResult() { return accumulator; } } --- NEW FILE: MaxFunction.java --- package org.jdaemon.util.functional; import java.util.Comparator; public class MaxFunction<T> implements BinaryFunction<T, T, T> { private final Comparator<T> comparator; public MaxFunction(Comparator<T> comp) { super(); this.comparator = comp; } /** compare a,b * * Note special semantics: * * if a = null, max(a,b) = b; * if b = null, max(a,b) = a; * * @param a * @param b * @return */ public T operate(T a, T b) { if (a == null) return b; if (b == null) return a; return comparator.compare(a, b) > 0 ? a : b; } } --- NEW FILE: CountFunction.java --- package org.jdaemon.util.functional; public class CountFunction<T> implements BinaryFunction<Long, T, Long> { public Long operate(Long a, T b) { if (a == null) a = 0L; if (b == null) return a; return a + 1L; } } Index: Operations.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/util/functional/Operations.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** Operations.java 19 Feb 2008 19:42:52 -0000 1.2 --- Operations.java 29 Jul 2008 22:41:07 -0000 1.3 *************** *** 8,14 **** import java.util.Collection; ! import java.util.Comparator; ! /** * * @author jonathan --- 8,14 ---- import java.util.Collection; ! import java.util.List; ! /** Library of operations which can be performed on UnaryFunction and BinaryFunction objects. * * @author jonathan *************** *** 16,21 **** public class Operations { ! public static <A, R1, R2> Unary<A,R2> Chain(final Unary<A,R1> f1, final Unary<R1, R2> f2) { ! return new Unary<A,R2>() { public R2 operate(A a) { return f2.operate(f1.operate(a)); --- 16,27 ---- public class Operations { ! /** Chain two unary functions together so that the second operates on the result of the first. ! * ! * @param f1 A unary function ! * @param f2 A unary function ! * @return a new unary function R where R.operate(x) is equivalent to f2.operate(f1.operate(x)) ! */ ! public static <A, R1, R2> UnaryFunction<A,R2> Chain(final UnaryFunction<A,R1> f1, final UnaryFunction<R1, R2> f2) { ! return new UnaryFunction<A,R2>() { public R2 operate(A a) { return f2.operate(f1.operate(a)); *************** *** 24,29 **** } ! public static <A,B, R1, R2> Binary<A,B,R2> Chain(final Binary<A,B,R1> f1, final Unary<R1, R2> f2) { ! return new Binary<A,B,R2>() { public R2 operate(A a, B b) { return f2.operate(f1.operate(a,b)); --- 30,41 ---- } ! /** Chain a unary functions together with a binary function so that the unary on the result of the binary. ! * ! * @param f1 A binary function ! * @param f2 A unary function ! * @return a new binary function R where R.operate(x,y) is equivalent to f2.operate(f1.operate(x,y)) ! */ ! public static <A,B, R1, R2> BinaryFunction<A,B,R2> Chain(final BinaryFunction<A,B,R1> f1, final UnaryFunction<R1, R2> f2) { ! return new BinaryFunction<A,B,R2>() { public R2 operate(A a, B b) { return f2.operate(f1.operate(a,b)); *************** *** 32,37 **** } ! public static <A1, A2, B, R> Binary<A1,B,R> ChainFirst(final Unary<A1, A2> f1, final Binary<A2, B, R> f2) { ! return new Binary<A1,B,R>() { public R operate(A1 a, B b) { return f2.operate(f1.operate(a), b); --- 44,55 ---- } ! /** Chain a unary functions together with a binary function so that the binary on the result of the unary. ! * ! * @param f1 A unary function ! * @param f2 A binary function ! * @return a new binary function R where R.operate(x,y) is equivalent to f2.operate(f1.operate(x), y) ! */ ! public static <A1, A2, B, R> BinaryFunction<A1,B,R> ChainFirst(final UnaryFunction<A1, A2> f1, final BinaryFunction<A2, B, R> f2) { ! return new BinaryFunction<A1,B,R>() { public R operate(A1 a, B b) { return f2.operate(f1.operate(a), b); *************** *** 40,45 **** } ! public static <A, B1, B2, R> Binary<A,B1,R> ChainSecond(final Unary<B1, B2> f1, final Binary<A, B2, R> f2) { ! return new Binary<A,B1,R>() { public R operate(A a, B1 b) { return f2.operate(a,f1.operate(b)); --- 58,69 ---- } ! /** Chain a unary functions together with a binary function so that the binary on the result of the unary. ! * ! * @param f1 A unary function ! * @param f2 A binary function ! * @return a new binary function R where R.operate(x,y) is equivalent to f2.operate(x, f1.operate(y)) ! */ ! public static <A, B1, B2, R> BinaryFunction<A,B1,R> ChainSecond(final UnaryFunction<B1, B2> f1, final BinaryFunction<A, B2, R> f2) { ! return new BinaryFunction<A,B1,R>() { public R operate(A a, B1 b) { return f2.operate(a,f1.operate(b)); *************** *** 47,53 **** }; } ! ! public static <A, B, R> Unary<B,R> BindFirst(final Binary<A,B,R> f, final A a) { ! return new Unary<B,R>() { public R operate(B b) { return f.operate(a, b); --- 71,83 ---- }; } ! ! /** Bind some value to a parameter of a binary function, hence creating a unary function ! * ! * @param f1 A binary function ! * @param a The value to bind ! * @return a new unary function R where R.operate(x) is equivalent to f1.operate(a, x) ! */ ! public static <A, B, R> UnaryFunction<B,R> BindFirst(final BinaryFunction<A,B,R> f, final A a) { ! return new UnaryFunction<B,R>() { public R operate(B b) { return f.operate(a, b); *************** *** 56,61 **** } ! public static <A, B, R> Unary<A,R> BindSecond(final Binary<A,B,R> f, final B b) { ! return new Unary<A,R>() { public R operate(A a) { return f.operate(a, b); --- 86,97 ---- } ! /** Bind some value to a parameter of a binary function, hence creating a unary function ! * ! * @param f1 A binary function ! * @param a The value to bind ! * @return a new unary function R where R.operate(x) is equivalent to f1.operate(x,a) ! */ ! public static <A, B, R> UnaryFunction<A,R> BindSecond(final BinaryFunction<A,B,R> f, final B b) { ! return new UnaryFunction<A,R>() { public R operate(A a) { return f.operate(a, b); *************** *** 63,68 **** }; } ! ! public static <T,I> T accumulate(final Binary<T,I,T> f, Collection<I> collection, T accumulator) { for(I item: collection) { accumulator = f.operate(accumulator, item); --- 99,114 ---- }; } ! ! /** Perform some function on all the values in a collection and return the result. ! * ! * Does accumulator = f.operate(item, accumulator) for every item in a collection, then returns ! * the final value of the accumulator variable. ! * ! * @param f A binary function ! * @param collection A collection of data items ! * @param accumulator Inital value of accumulator variable ! * @return the final value of the accumulator ! */ ! public static <T,I> T accumulate(final BinaryFunction<T,I,T> f, final Collection<I> collection, T accumulator) { for(I item: collection) { accumulator = f.operate(accumulator, item); *************** *** 70,118 **** return accumulator; } ! ! static class Test { ! public String stringv; ! public Integer intv; ! public Test(String a, Integer i) { stringv = a; intv = i; } } ! public static void main(String[] args) { ! ! Unary<Test,String> str_a = new Unary<Test,String>() { ! public String operate(Test t) { ! return t.stringv; } ! }; ! ! Unary<Test,Integer> int_a = new Unary<Test,Integer>() { ! public Integer operate(Test t) { ! return t.intv; ! } ! }; ! ! Binary<Double,Integer,Double> sum = new Sum<Integer>(); ! Binary<String, String, String> max = new Max<String>(String.CASE_INSENSITIVE_ORDER); ! ! Binary<Double,Test,Double> sum_int_a = ChainSecond(int_a, sum); ! Binary<String,Test,String> max_str_a = ChainSecond(str_a, max); ! ! Accumulator<Test, ? extends Object> a1 = new Accumulator<Test, Double>(0.0, sum_int_a); ! Accumulator<Test, ? extends Object> a2 = new Accumulator<Test, String>("", max_str_a); ! ! Test t1 = new Test("abcc", 27); ! Test t2 = new Test("def", 2); ! ! a1.accumulate(t1); ! a2.accumulate(t1); ! ! System.out.println("A1:" + a1.getResult() +",A1:"+ a2.getResult()); ! ! a1.accumulate(t2); ! a2.accumulate(t2); ! ! System.out.println("A1:" + a1.getResult() +",A1:"+ a2.getResult()); ! } ! ! ! } --- 116,154 ---- return accumulator; } ! ! /** Create an accumulator object from a binary function and an initial value. ! * ! * An accumulator object wraps a binary function f(x,y) and an inital value for the accumulator ! * value, a. Each call to the accumulate method with a value i results in accumulator = f(accumulator, i). ! * A call to the getResult method returns the current value of the accumulator. ! * ! * @param f Accumulation function ! * @param value initial value ! * @return An accumulator object. ! */ ! public static <T,I> Accumulator<I,T> newAccumulator(final BinaryFunction<T,I,T> f, T value) { ! return new FunctionAccumulator<I,T>(value,f); } ! /** Perform several functions on all the values in a collection and return the results. ! * <p> ! * Calls accumulate(item) for every accumulator in accumulators for every item in collection. ! * </p><p> ! * For an accumulator acc created with acc=newAccumulator(f,x), acc.getResult() should be equal to ! * accumulate(f, collection, x) once accumulate(Collections.singleList(acc), collection) has been called. ! * In other words, this method allows us to perform several accumulation operations while iterating over ! * a collection only once. ! * </p> ! * ! * ! * @param accumulators A list of accumulator obects ! * @param collection A collection of data items ! */ ! public static <I> void accumulate(List<Accumulator<I,?>> accumulators, final Collection<I> collection) { ! for(I item: collection) { ! for (Accumulator<I,?> accumulator : accumulators) { ! accumulator.accumulate(item); } ! } ! } } Index: Accumulator.java =================================================================== RCS file: /cvsroot/era/src/org/jdaemon/util/functional/Accumulator.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Accumulator.java 19 Feb 2008 19:42:52 -0000 1.1 --- Accumulator.java 29 Jul 2008 22:41:09 -0000 1.2 *************** *** 1,21 **** ! package org.jdaemon.util.functional; ! ! public class Accumulator<T, R> { ! ! private R accumulator; ! private Binary<R, T, R> fn; ! ! public Accumulator(R a, Binary<R, T, R> f) { ! super(); ! accumulator = a; ! fn = f; ! } ! public void accumulate(T t) { ! accumulator = fn.operate(accumulator, t); ! } ! public R getResult() { ! return accumulator; ! } } --- 1,16 ---- ! /* ! * To change this template, choose Tools | Templates ! * and open the template in the editor. ! */ ! package org.jdaemon.util.functional; ! /** ! * ! * @author jonathan ! */ ! public interface Accumulator<T,R> { ! ! public void accumulate(T t); ! public R getResult(); } --- Sum.java DELETED --- --- Unary.java DELETED --- --- Max.java DELETED --- --- Count.java DELETED --- --- Binary.java DELETED --- --- Min.java DELETED --- |