Java tutorial
//package com.java2s; //License from project: Open Source License import java.util.*; import java.util.function.BiFunction; public class Main { public static <T> List<T> innerJoin(List<List<T>> list, BiFunction<T, T, T> function) { if (list == null || function == null) { throw new NullPointerException("list or function must not be null"); } if (list.isEmpty()) { return Collections.emptyList(); } if (list.size() == 1) { return list.get(0); } List<List<T>> result = innerJoin(list.get(0), list.get(1), function); if (list.size() == 2) { return merge(result); } else { for (int i = 2; i < list.size(); i++) { List<T> l1 = list.get(i); List<List<T>> temp = new ArrayList<>(); result.stream().forEach(l -> temp.addAll(innerJoin(l, l1, function))); result = temp; } return merge(result); } } public static <T> List<List<T>> innerJoin(List<T> l1, List<T> l2, BiFunction<T, T, T> function) { if (l1 == null || l2 == null) { throw new NullPointerException("inner join arrays must not be null"); } if (l1.isEmpty() && l2.isEmpty()) { return Collections.emptyList(); } else if (l1.isEmpty()) { return Collections.singletonList(l2); } else if (l2.isEmpty()) { return Collections.singletonList(l1); } List<List<T>> result = new ArrayList<>(l1.size() * l2.size()); l1.stream().forEach(t1 -> { List<T> l = new ArrayList<>(); l2.stream().forEach(t2 -> l.add(function.apply(t1, t2))); result.add(l); }); return result; } public static <T> List<T> merge(List<List<T>> list) { List<T> result = new ArrayList<>(); list.stream().forEach(result::addAll); return result; } }