Skip to content

Commit

Permalink
Added forEach, map and foldLeft capable collection
Browse files Browse the repository at this point in the history
  • Loading branch information
mav911 committed Feb 8, 2012
1 parent 6cf3aa9 commit 929c1f5
Show file tree
Hide file tree
Showing 6 changed files with 272 additions and 0 deletions.
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
package com.blogspot.hartsock.functionalthinking;

import com.blogspot.hartsock.functionalthinking.functions.BinaryFunction;
import com.blogspot.hartsock.functionalthinking.functions.Function;
import com.blogspot.hartsock.functionalthinking.functions.UnaryFunction;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;

/**
* @author mansoor
* @since 2/7/12
*/
public class FPCollection<T> implements Collection<T> {
final Collection<T> collection;

public FPCollection() {
collection = new ArrayList<T>();
}

public FPCollection(Collection<T> collection) {
this.collection = collection;
}

public FPCollection(final T... values ) {
this.collection = new ArrayList<T>(Arrays.asList(values));
}

@Override
public int size() {
return collection.size();
}

@Override
public boolean isEmpty() {
return collection.isEmpty();
}

@Override
public boolean contains(Object o) {
return collection.contains(o);
}

@Override
public Iterator<T> iterator() {
return collection.iterator();
}

@Override
public Object[] toArray() {
return collection.toArray();
}

@Override
public <T> T[] toArray(T[] ts) {
return collection.toArray(ts);
}

@Override
public boolean add(T t) {
return collection.add(t);
}

@Override
public boolean remove(Object o) {
return collection.remove(o);
}

@Override
public boolean containsAll(Collection<?> objects) {
return collection.contains(objects);
}

@Override
public boolean addAll(Collection<? extends T> ts) {
return collection.addAll(ts);
}

@Override
public boolean removeAll(Collection<?> objects) {
return collection.removeAll(objects);
}

@Override
public boolean retainAll(Collection<?> objects) {
return collection.retainAll(objects);
}

@Override
public void clear() {
collection.clear();
}

/**
* Applies the given function to each element in the collection
* @param function function that will be applied
*/
public void forEach(final Function<T> function) {
if (function != null) {
for (T t : collection) {
function.apply(t);
}
}
}

/**
* Transform this collection to a new collection by applying given
* function to each element of this collection
* @param function function that will be applied
* @param <B> Type of new collection
* @return Collection of type B
*/
public <B> FPCollection<B> map(final UnaryFunction<T, B> function) {
FPCollection<B> result = new FPCollection<B>();
if (function != null) {
for (T t : collection) {
final B b = function.apply(t);
result.add(b);
}
}
return result;
}

/**
* The infamous FoldLeft method, also know as FOLDL in Haskell, FoldLeft in Scala
* and Inject in Ruby
* @param seed initial value
* @param function function that will be applied
* @param <B> type of the result
* @return return Object of type B
*/
public <B> B foldLeft(final B seed, final BinaryFunction<T, B> function) {
B result = seed;
if(function!=null){
for (T t : collection) {
result=function.apply(result,t);
}
}
return result;
}

@Override
public String toString() {
return foldLeft(new StringBuilder(),new BinaryFunction<T, StringBuilder>() {
public StringBuilder apply(StringBuilder seed, T input) {
seed.append(input).append(" ");
return seed;
}
}).toString();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.blogspot.hartsock.functionalthinking.functions;

/**
* @author Muhammad Ashraf
* @since 2/7/12
*/
public interface BinaryFunction<A,B> {

/**
* Lamda of kind (A,B) -> B
* @param seed seed value
* @param input input
* @return result of Binary operation
*/
B apply(final B seed,final A input);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.blogspot.hartsock.functionalthinking.functions;

/**
* @author Muhammad Ashraf
* @since 2/7/12
*/
public interface Function<T> {

/**
* lamda of type A -> Void
* @param input input
*/
void apply(final T input);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.blogspot.hartsock.functionalthinking.functions;

/**
*
* @author Muhammad Ashraf
* @since 2/7/12
*/
public interface UnaryFunction<A,B> {

/**
* Lambda of kind A -> B
* @param input input
* @return result of lambda operation
*/
B apply(final A input);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package com.blogspot.hartsock.functionalthinking;

import com.blogspot.hartsock.functionalthinking.functions.BinaryFunction;
import com.blogspot.hartsock.functionalthinking.functions.Function;
import com.blogspot.hartsock.functionalthinking.functions.UnaryFunction;
import org.junit.Assert;
import org.junit.Test;

import java.util.Collection;

/**
* @author Muhammad Ashraf
* @since 2/7/12
*/
public class FPCollectionTest {

@Test
public void testForEach() throws Exception {
FPCollection<String> collection=new FPCollection<String>("To","love,","or","not","to","love:","that","is","the","question");

collection.forEach(new Function<String>() {
public void apply(String input) {
System.out.println(input);
}
});



}

@Test
public void testMap() throws Exception {
FPCollection<Integer> collection=new FPCollection<Integer>(1,2,3,4,5,6,7,8,9,10);

final Collection<String> result = collection.map(new UnaryFunction<Integer, String>() {
public String apply(Integer input) {
return input%2==0?"even":"odd";
}
});

System.out.println("result = " + result);
}

@Test
public void testFoldLeftSum() throws Exception {
FPCollection<Integer> collection=new FPCollection<Integer>(1,2,3,4,5,6,7,8,9,10);

final Integer sum = collection.foldLeft(0, new BinaryFunction<Integer, Integer>() {
public Integer apply(Integer seed, Integer input) {
return seed + input;
}
});

final Integer expected=55;
Assert.assertEquals("incorrect sum ", expected, sum);
}

@Test
public void testFoldLeftString() throws Exception {
FPCollection<String> collection=new FPCollection<String>("To","love,","or","not","to","love:","that","is","the","question");

final String result = collection.foldLeft("", new BinaryFunction<String, String>() {
public String apply(String seed, String input) {
return seed + " " + input;
}
});

final String expected = " To love, or not to love: that is the question";
Assert.assertEquals("incorrect result", expected, result);
}

}

0 comments on commit 929c1f5

Please sign in to comment.