fitgoodies-core/src/main/java/de/cologneintelligence/fitgoodies/RowFixture.java
private void groupAndMatch(List<FitRow> expected, List<Object> computed, int col) {
        Map<Object, List<FitRow>> expectedMap = groupExpectedByColumn(expected, col);
        Map<Object, List<Object>> computedMap = groupComputedByColumn(computed, col);
        Set keys = union(expectedMap.keySet(), computedMap.keySet());

        for (Object key : keys) {
            List<FitRow> expectedList = expectedMap.get(key);
            List<Object> computedList = computedMap.get(key);

            boolean isAmbiguous = hasMultipleEntries(expectedList) && hasMultipleEntries(computedList);

            if (isAmbiguous) {
                multiLevelMatch(expectedList, computedList, col + 1);
            } else {
                check(expectedList, computedList);
            }
        }
    }
private void groupAndMatch(List<FitRow> expected, List<Object> computed, int col) {
        Map<Object, List<FitRow>> expectedMap = groupExpectedByColumn(expected, col);
        Map<Object, List<Object>> computedMap = groupComputedByColumn(computed, col);
        Set keys = union(expectedMap.keySet(), computedMap.keySet());

        for (Object key : keys) {
            List<FitRow> expectedList = expectedMap.get(key);
            List<Object> computedList = computedMap.get(key);

            boolean isAmbiguous = hasMultipleEntries(expectedList) && hasMultipleEntries(computedList);

            if (isAmbiguous) {
                multiLevelMatch(expectedList, computedList, col + 1);
            } else {
                check(expectedList, computedList);
            }
        }
    }
Groups both lists by column {@code col}. For every resulting group check if
there is a 1:1 or a 1:0 match. Otherwise, group further.