DataSourceUtils { public static <I, O> void crossProduct(List<I> left, List<I> right, Function<I, List<O>> transformer, BiConsumer<Pair<Integer, Integer>, List<O>> rowConsumer) { final int SIZE = left.size() * right.size(); for (int i = 0; i < SIZE; i++) { List<O> newRowValues = new ArrayList<>(); int j = 1; List<Integer> currentIndexes = new ArrayList<>(); for (List<I> rowsList : new ArrayList<List<I>>() { { add(left); add(right); } }) { final int index = ( i / j ) % rowsList.size(); currentIndexes.add(index); I row = rowsList.get(index); List<O> rowPart = transformer.apply(row); newRowValues.addAll(rowPart); j *= rowsList.size(); } if (currentIndexes.size() == 2) { rowConsumer.accept(new Pair<>(currentIndexes.get(0), currentIndexes.get(1)), newRowValues); } } }  static DataSource getTail(DataSource dataSource); static void addToDataSource(DataSource parent, DataSource child); static void checkLeftDataSource(DataSource dataSource); static void checkLeftDataSource(DataSource dataSource, boolean conditionRequired); static void checkRightDataSource(DataSource dataSource); static void checkRightDataSource(DataSource dataSource, boolean conditionRequired); static Set<T> intersection(Set<T> first, Set<T> second); static Set<T> difference(Set<T> first, Set<T> second); static Optional<BooleanExpression> intersectConditions(Optional<BooleanExpression> left, Optional<BooleanExpression> right); static void iterateDataSource(DataSource dataSource, DataSourceAction action); static void crossProduct(List<I> left, List<I> right, Function<I, List<O>> transformer, BiConsumer<Pair<Integer, Integer>, List<O>> rowConsumer); static List<List<T>> crossProduct(List<Collection<T>> lists);  }
@Test public void testCrossProductEmpty() { assertThat(crossProduct(null), is(empty())); assertThat(crossProduct(Collections.emptyList()), is(empty())); }
@Test public void testCrossProductSingle() { List<Collection<String>> input = Collections.singletonList(Arrays.asList("1", "2")); List<List<String>> output = crossProduct(input); assertThat(output, equalTo(Arrays.asList(Collections.singletonList("1"), Collections.singletonList("2")))); }
@Test public void testCrossProductMultiple() { List<List<String>> output = crossProduct(Arrays.asList( Arrays.asList("1", "2"), Arrays.asList("3", "4"), Arrays.asList("5", "6") )); assertThat(output, hasSize(8)); assertThat(output, contains( Arrays.asList("1", "3", "5"), Arrays.asList("1", "4", "5"), Arrays.asList("1", "3", "6"), Arrays.asList("1", "4", "6"), Arrays.asList("2", "3", "5"), Arrays.asList("2", "4", "5"), Arrays.asList("2", "3", "6"), Arrays.asList("2", "4", "6") )); }
@Test public void testCrossProductWithConsumer() { List<List<String>> output = new ArrayList<>(); crossProduct( Arrays.asList("1", "2"), Arrays.asList("1", "4"), Collections::singletonList, (pair, row) -> output.add(row) ); assertThat(output, hasSize(4)); assertThat(output, contains( Arrays.asList("1", "1"), Arrays.asList("2", "1"), Arrays.asList("1", "4"), Arrays.asList("2", "4") )); }