假设我有以下谓词作为Villager POJO的预定义lambda。
val matchesSearch: (Villager, String) -> Boolean =
{ villager: Villager, query: String -> villager.name.contains(query) }
val matchesGender: (Villager, Int) -> Boolean =
{ villager: Villager, filter: Int -> filter == villager.gender }
val matchesPersonality: (Villager, Int) -> Boolean =
{ villager: Villager, filter: Int -> filter == villager.personality }
val matchesSpecies: (Villager, Int) -> Boolean =
{ villager: Villager, filter: Int -> filter == villager.species }
val matchesHobby: (Villager, Int) -> Boolean =
{ villager: Villager, filter: Int -> filter == villager.hobby }
我只想在满足特定条件的情况下应用谓词。例如,如果已应用性别过滤器,则仅按性别过滤。或者,如果输入了一个查询,我只想与搜索查询匹配。
fun getVillagersThatMatchQueryAndFilters(list: List<Villager>): List<Villager> {
val conditions = ArrayList<Predicate<Villager>>()
if (searchQuery.isNotEmpty()) {
// TODO: apply the matchesSearch() predicate lambda
conditions.add(Predicate { villager -> villager.name.contains(query) })
}
if (genderFilter > 0) {
// TODO: apply the matchesGender() predicate lambda
conditions.add(Predicate { genderFilter == villager.gender })
}
if (personalityFilter > 0) {
// TODO: apply the matchesPersonality() predicate lambda
conditions.add(Predicate { personalityFilter == villager.personality })
}
if (speciesFilter > 0) {
// TODO: apply the matchesSpecies() predicate lambda
conditions.add(Predicate { speciesFilter == villager.species })
}
if (hobbyFilter > 0) {
// TODO: apply the matchesHobby() predicate lambda
conditions.add(Predicate { hobbyFilter == villager.hobby })
}
return list.filter {
// TODO: match on all conditionally applied predicates
conditions.allPredicatesCombinedWithAnd() // this doesn't actually exist
}
}
[以前,我在每个条件下都完成了list.filter{ }
并应用了必要的谓词,但是,由于我最多可以应用5个谓词,因此每次调用.filter()
都会在列表中进行迭代,因此性能非常糟糕。 。
是否可以通过编程方式遍历List<Predicate<T>>
并将谓词与.and()
或&&
组合在一起,以便我可以一次应用过滤器?否则,该如何有条件地合并这些谓词?
我将使用使用here和Predicates.stream()
的最终Java示例Collectors
,但它需要Android API级别24(高于我当前的Android分钟)。
具有all扩展功能,并且同样值得关注的是any扩展功能。我认为您只需要在谓词的过滤器块中使用它们即可。这是一个非常简单的示例,包含一组愚蠢的谓词:
fun main() {
val thingsToFilter = listOf(-1,2,5)
val predicates = listOf(
{ value: Int -> value > 0 },
{ value: Int -> value > 4 }
)
val filtered = thingsToFilter.filter {candidate ->
// Get a list of booleans from predicates. Check all of them are true.
predicates.map { it(candidate) }.all { it }
}
print(filtered) // Outputs [5]
}