Java Lambda 创建一个带有判断 Levenshtein 距离是否大于 2 的谓词函数的过滤器

Java Lambda create a filter with a predicate function which determines if the Levenshtein distance is greater than 2

我有一个查询以获得最相似的值。好吧,我需要定义最小 Levenshtein 距离结果。如果分数大于 2,我不想将该值视为推荐的一部分。

String recommendation =  candidates.parallelStream()
            .map(String::trim) 
            .filter(s -> !s.equals(search))
            .min((a, b) -> Integer.compare(
              cache.computeIfAbsent(a, k -> StringUtils.getLevenshteinDistance(Arrays.stream(search.split(" ")).sorted().toString(), Arrays.stream(k.split(" ")).sorted().toString()) ),
              cache.computeIfAbsent(b, k -> StringUtils.getLevenshteinDistance(Arrays.stream(search.split(" ")).sorted().toString(), Arrays.stream(k.split(" ")).sorted().toString()))))
            .get();

你的问题是一个单一的过滤操作:如何排除得分大于2的元素。你需要为它写一个谓词。可以在不知道有关应用程序逻辑其余部分的任何细节的情况下编写的最简单的谓词形式如下:

.filter(s -> StringUtils.getLevenshteinDistance(search, s) <= 2)

考虑到您将 Levenshtein 分数缓存在 HashMap 中,应该这样重写谓词:

.filter(s -> cache.computeIfAbsent(s, k -> StringUtils.getLevenshteinDistance(search, k)) <= 2)

现在,如果您想对元素执行任何其他操作,例如拆分、重新排序和合并它们,您可以进一步增强此代码,但这超出了您的问题范围。

尽管如此,说到 splitting/joining,让我更正您代码中的一个错误。行

Arrays.stream(search.split(" ")).sorted().toString()

并没有真正做任何有用的事情。它只会打印 Stream 实例的哈希码。我猜你想完成这个:

Arrays.stream(s.split(" ")).sorted().collect(Collectors.joining(" "))

此代码将按字母顺序重新排列单词链:"Malus Casus" -> "Casus Malus"