How to implement a list fold in Java

Peter Kofler picture Peter Kofler · Jun 4, 2009 · Viewed 30.7k times · Source

I have a List and want to reduce it to a single value (functional programming term "fold", Ruby term inject), like

Arrays.asList("a", "b", "c") ... fold ... "a,b,c"

As I am infected with functional programming ideas (Scala), I am looking for an easier/shorter way to code it than

sb = new StringBuilder
for ... {
  append ...
}
sb.toString

Answer

Apocalisp picture Apocalisp · Jun 4, 2009

To answer your original question:

public static <A, B> A fold(F<A, F<B, A>> f, A z, Iterable<B> xs)
{ A p = z;
  for (B x : xs)
    p = f.f(p).f(x);
  return p; }

Where F looks like this:

public interface F<A, B> { public B f(A a); }

As dfa suggested, Functional Java has this implemented, and more.

Example 1:

import fj.F;
import static fj.data.List.list;
import static fj.pre.Monoid.stringMonoid;
import static fj.Function.flip;
import static fj.Function.compose;

F<String, F<String, String>> sum = stringMonoid.sum();
String abc = list("a", "b", "c").foldLeft1(compose(sum, flip(sum).f(",")));

Example 2:

import static fj.data.List.list;
import static fj.pre.Monoid.stringMonoid;
...
String abc = stringMonoid.join(list("a", "b", "c"), ",");

Example 3:

import static fj.data.Stream.fromString;
import static fj.data.Stream.asString;
...
String abc = asString(fromString("abc").intersperse(','));