RootTermDistanceCalculator { public static String nearestRootTerm(Set<RootTermDistanceCalculator> distanceCalculators, String term, int threshold) { if(threshold < 0) { throw new IllegalArgumentException("Threshold must be greater than or equal to 0"); } var calculatorMindDistanceEntries = distanceCalculators.parallelStream() .collect(Collectors.toMap( Function.identity(), distanceCalculator -> distanceCalculator.calculateMinimalDistance(term) )) .entrySet(); var minDistanceEntry = Collections.min(calculatorMindDistanceEntries, Comparator.comparingInt(Map.Entry::getValue)); if(minDistanceEntry.getValue() <= threshold) { return minDistanceEntry.getKey().getOriginalRootTerm(); } else { return term; } } RootTermDistanceCalculator(String rootTerm, Set<String> derivedTerms); int calculateMinimalDistance(String stringToMatch); static String nearestRootTerm(Set<RootTermDistanceCalculator> distanceCalculators, String term, int threshold);  }
@Test public void nearestRootTermReturnsExactlyMatchingRootTerm() { var firstCalcRootTerm = "tomato"; var secondCalcRootTerm = "apple"; var term = firstCalcRootTerm; var firstCalc = new RootTermDistanceCalculator(firstCalcRootTerm, Set.of()); var secondCalc = new RootTermDistanceCalculator(secondCalcRootTerm, Set.of()); var calculators = Set.of(firstCalc, secondCalc); var actualNearestRootTerm = RootTermDistanceCalculator.nearestRootTerm(calculators, term, 100); assertThat(actualNearestRootTerm).isEqualTo(firstCalcRootTerm); }
@Test public void nearestRootTermReturnsNearestMatchingRootTerm() { var firstCalcRootTerm = "tomato"; var firstCalcDerivedTerms = Set.of("tmato"); var secondCalcRootTerm = "apple"; var secondCalcDerivedTerms = Set.of("appel"); var term = "apppel"; var firstCalc = new RootTermDistanceCalculator(firstCalcRootTerm, firstCalcDerivedTerms); var secondCalc = new RootTermDistanceCalculator(secondCalcRootTerm, secondCalcDerivedTerms); var calculators = Set.of(firstCalc, secondCalc); var actualNearestRootTerm = RootTermDistanceCalculator.nearestRootTerm(calculators, term, 100); assertThat(actualNearestRootTerm).isEqualTo(secondCalcRootTerm); }
@Test public void nearestRootTermReturnsTermWhenThresholdIsExceeded() { var rootTerm = "banana"; var derivedTerms = Set.of("yellow-thing", "monkey-snack"); var term = "ylow-thing"; var threshold = 1; var calculator = new RootTermDistanceCalculator(rootTerm, derivedTerms); var actualRootTerm = RootTermDistanceCalculator.nearestRootTerm(Set.of(calculator), term, threshold); assertThat(actualRootTerm).isEqualTo(term); }