JaroMatcher extends AbstractAttributeMatcher { @Override public double getWeight(String string1, String string2) { int str1CPCount = string1.codePointCount(0, string1.length()); int str2CPCount = string2.codePointCount(0, string2.length()); final int halflen = ((Math.min(str1CPCount, str2CPCount)) / 2) + ((Math.min(str1CPCount, str2CPCount)) % 2); final StringBuilder common1 = StringComparisonUtil.getCommonCharacters(string1, string2, halflen); final StringBuilder common2 = StringComparisonUtil.getCommonCharacters(string2, string1, halflen); if (common1.length() == 0 || common2.length() == 0) { return 0.0f; } if (common1.codePoints().count() != common2.codePoints().count()) { return 0.0f; } int common1CPCount = common1.codePointCount(0, common1.length()); int common2CPCount = common2.codePointCount(0, common2.length()); int transpositions = 0; int cp1; for (int i = 0; i < common1.length(); i += Character.charCount(cp1)) { cp1 = common1.codePointAt(i); if (cp1 != common2.codePointAt(i)) transpositions++; } transpositions /= 2.0f; return (common1CPCount / ((float) str1CPCount) + common2CPCount / ((float) str2CPCount) + (common1CPCount - transpositions) / ((float) common1CPCount)) / 3.0f; }  @Override AttributeMatcherType getMatchType(); @Override double getWeight(String string1, String string2);  }
@Test public void testGetWeight() { JaroMatcher jaroMatcher = new JaroMatcher(); String a = "John"; String b = "Jon"; double matchingWeight = jaroMatcher.getMatchingWeight(a, b); assertEquals(0.9166666865348816d, matchingWeight, EPSILON); a = "23"; matchingWeight = jaroMatcher.getMatchingWeight(a, a); assertEquals("input strings are the same => result should be 1.", 1.0d, matchingWeight, EPSILON); b = "64"; matchingWeight = jaroMatcher.getMatchingWeight(a, b); assertNotSame("input strings are the same => result should NOT be 1.", 1.0d, matchingWeight); String c = " "; matchingWeight = jaroMatcher.getMatchingWeight(c, c); assertEquals("input strings are the same => result should be 1.", 1.0d, matchingWeight, EPSILON); a = "JohnFit"; b = "JohnFitzgeraldKennedy"; matchingWeight = jaroMatcher.getMatchingWeight(a, b); assertTrue("input strings are not the same but should not be able to distinguish between " + a + " and " + b, 0.7777778506278992d == matchingWeight); a = "\n"; b = "Hulme"; matchingWeight = jaroMatcher.getMatchingWeight(a, b); assertTrue("input strings are not the same " + a + " and " + b, 0.0d == matchingWeight); a = "拓蓝科技"; b = "拓蓝"; matchingWeight = jaroMatcher.getMatchingWeight(a, b); assertEquals(0.8333333134651184d, matchingWeight, EPSILON); }
@Test public void testGetWeightSurrogate() { JaroMatcher matcher = new JaroMatcher(); double weight = matcher.getMatchingWeight("𠀠𠀡𠀢", "𠀠"); assertEquals(0.7777778506278992d, weight, EPSILON); weight = matcher.getWeight("𠀐𠀑𠀔", "𠀐𠀑𠀔"); assertEquals(1.0d, weight, 0); weight = matcher.getWeight("𠀐𠀑a", "𠀒𠀓𠀔"); assertEquals(0d, weight, 0); weight = matcher.getWeight("𠀐𠀑a", "𠀒𠀑c"); assertEquals(0.5555555820465088d, weight, 0); }