Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Port Erlang permutation function to Java 8 with lambda expressions and Streams

Is it possible to write the following Erlang code only with Java 8 lambda expressions and Java 8 streams? This is from List Comprehensions 3.3 Permutations

perms([]) -> [[]];
perms(L)  -> [[H|T] || H <- L, T <- perms(L--[H])].
like image 897
Thomas Darimont Avatar asked Aug 12 '14 07:08

Thomas Darimont


1 Answers

Using a ternary op to replace pattern matching, flatMap to replace multiple generators, and static methods to implement | and -- operations:

import static java.util.stream.Collectors.toList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class Example {

    public static <E> List<E> pipe(E head, List<E> tail) {
        List<E> newList = new ArrayList<>(tail);
        newList.add(0, head);
        return newList;
    }

    public static <E> List<E> subtract(List<E> list, E e) {
        List<E> newList = new ArrayList<>(list);
        newList.remove(e);
        return newList;
    }

    public static <E> List<List<E>> perms(List<E> l) {
        return l.isEmpty()
                ? Collections.singletonList(Collections.emptyList())
                : l.stream().<List<E>> flatMap(h -> perms(subtract(l, h)).stream().map(t -> pipe(h, t)))
                        .collect(toList());
    }

    public static void main(String[] args) {
        List<String> list = Arrays.asList(new String[] { "b", "u", "g" });
        System.out.println(perms(list));
    }
}

The explicit type specification at .<List<E>> flatMap( is only necessary due to inadequate type inference from the Java compiler.

like image 186
Sean Van Gorder Avatar answered Sep 25 '22 06:09

Sean Van Gorder