Java 使用谓词的泛型集合筛选

Java 使用谓词的泛型集合筛选,java,kotlin,filter,collections,predicate,Java,Kotlin,Filter,Collections,Predicate,我在kotlin遇到了一个关于收集过滤的棘手问题 我得到了一个管理项目列表的基类,我希望能够使用关键字筛选列表,因此我使用可筛选方法扩展了该类 我想做的是能够用这个“基类”扩展多个类,这样所有类的过滤机制都是相同的 这些类没有相同的属性。。。在一个类中,过滤必须根据关键字是否在“name”中找到而在另一个类中过滤是在“comment”属性上完成的 下面是一些代码: data class ProductInfo(): { var _name: String var name: St

我在kotlin遇到了一个关于收集过滤的棘手问题

我得到了一个管理项目列表的基类,我希望能够使用关键字筛选列表,因此我使用可筛选方法扩展了该类

我想做的是能够用这个“基类”扩展多个类,这样所有类的过滤机制都是相同的

这些类没有相同的属性。。。在一个类中,过滤必须根据关键字是否在“name”中找到而在另一个类中过滤是在“comment”属性上完成的

下面是一些代码:

data class ProductInfo(): {
    var _name: String
    var name: String
            get() = _name
            set(value) { _name = value }
}

abstract class BaseFirestoreAdapter<T : BaseFirestoreAdapter.DataInterface, VH : RecyclerView.ViewHolder> : RecyclerView.Adapter<VH>(), Filterable
{

    var sourceList: MutableList<ProductInfo> = ArrayList()

    ...

    override fun performFiltering(keyword: CharSequence): FilterResults {

        val keywordRegex = keyword.toString().toRegex(setOf(RegexOption.IGNORE_CASE, RegexOption.LITERAL))

        filteredList = sourceList.filter {
                keywordRegex.containsMatchIn(Normalizer.normalize(it.name, Normalizer.Form.NFD).replace("[^\\p{ASCII}]".toRegex(RegexOption.IGNORE_CASE), ""))
        }

        results.values = filteredList.sortedWith(orderComparator)
        results.count = filteredList.size
    }

    ...
}
数据类ProductInfo():{
变量名称:String
变量名称:String
get()=\u名称
设置(值){u name=value}
}
抽象类BaseFirestoreAdapter:RecyclerView.Adapter(),可筛选
{
var sourceList:MutableList=ArrayList()
...
override fun performFiltering(关键字:CharSequence):FilterResults{
val keywordRegex=keyword.toString().toRegex(setOf(RegexOption.IGNORE_CASE,RegexOption.LITERAL))
filteredList=sourceList.filter{
关键字regex.containsMatchIn(Normalizer.normalize(it.name,Normalizer.Form.NFD)。替换(“[^\\p{ASCII}]”)。toRegex(RegexOption.IGNORE_CASE),“”)
}
results.values=filteredList.sortedWith(orderComparator)
results.count=filteredList.size
}
...
}
我开发了“基类”,这样它就可以和上面提到的第一个类一起工作(过滤是用“it.name”完成的),它也可以工作,但是现在我正试图使它通用(T)以与第二个类(注释)一起使用,我找不到一种方法来做它

我想我可以传递一个与类相关的谓词,定义如何在筛选过程中匹配项,但由于关键字仅在performFiltering方法中已知,因此我无法在此方法之外正确创建谓词

我现在有点不知所措了!哈哈

你们有什么想法吗


更新:根据@Tenfour04的建议,我尝试将其改编为我的代码,该代码通过方法传递过滤谓词,而不是使用构造函数,但它不会编译,除非我将“ActivyInfo::comments”替换为类似“ActivyInfo::comments.name”的内容,但是 我在调试中为“searchedProperty(it)”获取的值是“name”,它不是注释值

代码如下:

评论适配器:

override fun getFilter(): Filter {

        super.setFilter(
                { it.state != ProductState.HIDDEN },
                { ActivyInfo::comments },
                compareBy<ProductInfo> { it.state }.thenBy(String.CASE_INSENSITIVE_ORDER) { it.name })

        return super.getFilter()
}
override fun getFilter():过滤器{
super.setFilter(
{it.state!=ProductState.HIDDEN},
{ActivyInfo::comments},
通过{it.state}.thenBy(String.CASE\u-INSENSITIVE\u-ORDER){it.name}进行比较
返回super.getFilter()
}
基本适配器:

lateinit var defaultFilterPredicate : (T) -> Boolean
lateinit var searchedProperty : (T) -> CharSequence
lateinit var orderComparator : Comparator<T>

fun setFilter(defaultPredicate: (T) -> Boolean, property: (T) -> CharSequence, comparator: Comparator<T> ) {
    defaultFilterPredicate = defaultPredicate
    searchedProperty = property
    orderComparator = comparator
}

override fun performFiltering(constraint: CharSequence): FilterResults {

        ...

        filteredList = sourceList.filter {
                constraintRegex.containsMatchIn(Normalizer.normalize(searchedProperty(it), Normalizer.Form.NFD).replace("[^\\p{ASCII}]".toRegex(RegexOption.IGNORE_CASE), ""))
        }

        ...

    }
lateinit var defaultFilterPredicate:(T)->布尔值
lateinit var searchedProperty:(T)->CharSequence
lateinit变量orderComparator:Comparator
fun setFilter(defaultPredicate:(T)->Boolean,property:(T)->CharSequence,comparator:comparator){
defaultFilterPredicate=defaultPredicate
searchedProperty=property
orderComparator=比较器
}
重写性能筛选(约束:CharSequence):FilterResults{
...
filteredList=sourceList.filter{
constraintRegex.containsMatchIn(Normalizer.normalize(searchedProperty(it),Normalizer.Form.NFD)。替换(“[^\\p{ASCII}]”)。toRegex(RegexOption.IGNORE_CASE),“”)
}
...
}

您可以将指定属性为函数的参数传递给构造函数

abstract class BaseFirestoreAdapter<T : BaseFirestoreAdapter.DataInterface, VH : RecyclerView.ViewHolder>(val filteredProperty: (T) -> CharSequence) : RecyclerView.Adapter<VH>(), Filterable
{

    var sourceList: MutableList<T> = ArrayList()

    // ...

    override fun performFiltering(keyword: CharSequence): FilterResults {

        val keywordRegex = keyword.toString().toRegex(setOf(RegexOption.IGNORE_CASE, RegexOption.LITERAL))

        filteredList = sourceList.filter {
                keywordRegex.containsMatchIn(Normalizer.normalize(filteredProperty(it), Normalizer.Form.NFD).replace("[^\\p{ASCII}]".toRegex(RegexOption.IGNORE_CASE), ""))
        }

        results.values = filteredList.sortedWith(orderComparator)
        results.count = filteredList.size
    }

    ...
}
或者,如果希望保持通用性:

class SomeDataAdapter(filteredProperty: (T) -> CharSequence): BaseFirestoreAdapter<SomeData>(filteredProperty) //...
class SomeDataAdapter(filteredProperty:(T)->CharSequence):BaseFirestoreAdapter(filteredProperty)/。。。

这与您的问题无关,但您的ProductInfo似乎有一些错误正在等待发生。它是一个没有构造函数参数的数据类,因此它的每个实例都将通过与任何其他实例的
equals
测试。另外,
\u name
name
属性具有非常不寻常和令人惊讶的行为,数据类比这复杂得多,有两个构造函数:-)我尝试将您的建议改编为我的代码,该代码通过一个方法而不是使用构造函数传递过滤谓词,但它不会编译,除非我将“ActivyInfo::comments”替换为“ActivyInfo::comments.name”之类的内容,然后是我得到的值调试中的“searchedProperty(it)”是“名称”“这不是注释值。关于代码,请参阅我更新的问题。谓词类型是一个具有输入类型T和输出类型CharSequence的函数。您可以通过传递
ActivityInfo::comments
直接传递函数/属性,也可以传递具有参数T并返回CharSequence的lambda,如
{it.comments}
,但您传递的是返回属性
{ActivityInfo::comments}
的lambda,因此它不起作用。哈!当然,哈哈,我忘了带牙套了哈哈,谢谢,它现在好像工作正常了!
class SomeDataAdapter(filteredProperty: (T) -> CharSequence): BaseFirestoreAdapter<SomeData>(filteredProperty) //...