public static int product(Listseq){ int product = 0; for(int i : seq){ product *= i; } return product; }
In Scala you can write the same code in one line:
val result = (1 to 10).fold(0)(_ * _)How about a method that counts a letters of words in a sentence?
public CollectioncountWords(Collection words){ Collection result = new ArrayList (); for(String word : words){ result.add(word.length()); } return result; }
Here is the same logic written in Scala:
words.map(_.length)So is there a way to do map and reduce in Java?
Yes, that's how I solved this problem. First, you'll need two classes that represents high-order functions of one and two arguments.
public interface Function1{ public R run(IN param); } public interface Function2 { public R run(IN1 param1, IN2 param2); }
Next, lets write our map and reduce methods.
public class CollectionUtils { public staticR fold(Collection sequence, R initialValue, Function2 action) { for (IN element : sequence) { initialValue = action.run(initialValue, element); } return initialValue; } public static Collection map(Collection sequence, Function1 action) { Collection result = new ArrayList<>(); for (IN element : sequence) { result.add(action.run(element)); } return result; } }
Now lets get back to our examples. Here is how you are going to do the product and word count examples with help of those methods. First you'll need two helper functions.
public class Functions { public static Function2Finally, one-liner that does product of number of letters of all words in a sentence.product() { return new Function2 () { @Override public Integer run(Integer param1, Integer param2) { return param1 * param2; } }; } public static Function1 countLetters() { return new Function1 () { @Override public Integer run(String param1) { return param1.length(); } }; } }
CollectionUtils.fold(CollectionUtils.map(Arrays.asList("The", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog"), Functions.countLetters()), 1, Functions.product());