Groovy实现两列表首个公共元素匹配即终止迭代(替代each方法)
解决Groovy嵌套循环中找到第一个匹配元素立即返回的问题
你的核心需求是找到第一个满足匹配条件的元素后立即终止所有迭代并返回该元素,原来的each嵌套循环会遍历所有元素,既浪费性能又没法提前终止,而你尝试find没成功大概率是嵌套使用的方式不对。
这里有两种更优雅且符合需求的实现方案:
方案一:利用嵌套find直接终止迭代
Groovy的find方法本身就会在找到第一个满足条件的元素时立即停止遍历并返回该元素,我们可以嵌套使用它来实现需求:
def buildMatchTeamsInCategoriesWithPreferences(def preferences, def teamsInCategories) { // 遍历teamsInCategories,找到第一个能匹配到preference的条目 return teamsInCategories.find { team -> // 在内层遍历preferences,找到第一个匹配的元素 def matchedPref = preferences.find { preference -> this.commonPresenter.getString(team?.uid) == this.commonPresenter.getString(preference?.metaData?.team?.uid) } // 如果找到匹配项,直接返回,外层find也会终止 matchedPref ?: null } }
方案二:预处理集合提升性能(推荐)
如果你的列表数据量较大,先把teamsInCategories的UID转换后存入集合,再用find遍历preferences会更高效(集合的contains操作是O(1)时间复杂度):
def buildMatchTeamsInCategoriesWithPreferences(def preferences, def teamsInCategories) { // 预处理:将teamsInCategories的所有UID转换后存入Set def targetUids = teamsInCategories.collect { team -> this.commonPresenter.getString(team?.uid) } as Set // 遍历preferences,找到第一个UID在目标集合中的元素,找到即返回 return preferences.find { preference -> def prefUid = this.commonPresenter.getString(preference?.metaData?.team?.uid) targetUids.contains(prefUid) } }
为什么这两种方案能解决你的问题?
- 两种方案都利用了Groovy
find方法的特性:找到第一个满足条件的元素后立即终止遍历,不需要像each那样遍历所有元素。 - 方案二通过预处理集合,把原来O(n*m)的时间复杂度降到了O(n+m),数据量大时性能提升明显。
- 最终返回的就是第一个匹配的
preference元素,不需要再从数组取[0]。
内容的提问来源于stack exchange,提问作者rasilvap
相关产品推荐
相关产品推荐

