I am making an launcher for my phone and I need to sort the apps by alphabet.

 Appslist = ArrayList<AppInfo>()

    val i = Intent(Intent.ACTION_MAIN, null)
    i.addCategory(Intent.CATEGORY_LAUNCHER)
    val allApps = this.packageManager.queryIntentActivities(i, 0)

    for (ri in allApps) {
        val app = AppInfo()
        app.label = ri.loadLabel(this.packageManager)
        app.packageName = ri.activityInfo.packageName
        app.icon = ri.activityInfo.loadIcon(this.packageManager)
        if(app.label?.toString()!!.length >= searchWord.length && app.label?.toString()!!.substring(0, searchWord.length) == searchWord.toUpperCase() && searchWord != "" ||
            app.label?.toString()!!.length >= searchWord.length && app.label?.toString()!!.substring(0, searchWord.length) == searchWord.toLowerCase() && searchWord != "" ||
            app.label?.toString()!!.length >= searchWord.length && app.label?.toString()!!.substring(0, searchWord.length) == searchWord.capitalize() && searchWord != "" ||
            app.label?.toString()!!.length >= searchWord.length && app.label?.toString()!!.substring(0, searchWord.length) == searchWord && searchWord != ""){

            if(app.packageName != "com.david.launcher" ){
                Appslist.add(app)
            }

        }
        if(searchWord == ""){
            if(app.packageName != "com.david.launcher"){
                Appslist.add(app)
            }
        }

    }

这是我的列表类型(我不知道它是否叫做列表类型,但我希望你能理解):

public class AppInfo {
internal var label: CharSequence? = null
internal var packageName: CharSequence? = null
internal var icon: Drawable? = null
internal var isInFav: Boolean? = false

推荐答案

如果您想要排序到列表的副本中,惯用的方法是对List使用sortedBy扩展方法.或者,如果您想在没有副本的情况下就地排序,请在MutableList上使用sortBy分机.ArrayList可以作为任一列表类型工作.

// Sort a readonly list into a copy of the list

val appsList: List<AppInfo> = ...

val sortedAppsList = appsList.sortedBy { it.label?.toString() }

对比:

// Sort a mutable list in-place

val appsList: MutableList<AppInfo> = ...

appList.sortBy { it.label?.toString() }

and if holding as an ArrayList it is the same, but not idiomatic to have a reference directly to this concrete type.

// Sort an ArrayList list into a copy of the list

val appsList: ArrayList<AppInfo> = ...  // ALERT! not idiomatic

val sortedAppsList = appsList.sortedBy { it.label?.toString() }

// or if you want, feel free to sort in-place

appsList.sortBy { it.label?.toString() }

Note the toString() on the label: CharSequence member. You have to be careful sorting on a reference of type CharSequence as it is undefined what is its behavior for sorting (see: https://docs.oracle.com/javase/7/docs/api/java/lang/CharSequence.html)

This interface does not refine the general contracts of the equals and hashCode methods. The result of comparing two objects that implement CharSequence is therefore, in general, undefined.

如果CharSequence已经是String(很可能是),那么呼叫toString()没有什么坏处,因为它只是返回自己.

还请记住,还必须处理可为null的CharSequence,并且您需要决定在哪里使用null:在列表的开头或结尾.我认为默认的做法是让他们从头开始.


Other notes about your code in the question:

Use the List or MutableList interface instead of the concrete class to reference the type, and use the methods from Kotlin stdlib to do actions upon the list. Also use val instead of var for references that will not change (meaning it will always point to the same list regardless of whether the list contents could change).

你的if大声明可以减少很多,从...

if(app.label?.toString()!!.length >= searchWord.length && app.label?.toString()!!.substring(0, searchWord.length) == searchWord.toUpperCase() && searchWord != "" ||
    app.label?.toString()!!.length >= searchWord.length && app.label?.toString()!!.substring(0, searchWord.length) == searchWord.toLowerCase() && searchWord != "" ||
    app.label?.toString()!!.length >= searchWord.length && app.label?.toString()!!.substring(0, searchWord.length) == searchWord.capitalize() && searchWord != "" ||
    app.label?.toString()!!.length >= searchWord.length && app.label?.toString()!!.substring(0, searchWord.length) == searchWord && searchWord != ""){

    if(app.packageName != "com.david.launcher" ){
        Appslist.add(app)
    }

}
if(searchWord == ""){
    if(app.packageName != "com.david.launcher"){
        Appslist.add(app)
    }
}

to simpler:

if (app.packageName != "com.david.launcher" &&
        (searchWord.isBlank() || 
         app.label?.startsWith(searchWord, ignoreCase = true) == true)) {
    appsList.add(app)
}

You should browse the standard library to get an idea of what is available so that you broaden your toolkit for the future.

Kotlin相关问答推荐

文本正在被切断在200%的屏幕比例在Jetpack Compose

判断字符串是否除了.&" ",","@""""

在构造函数中创建内部类实例时,只能使用包含类的接收器调用内部类的构造函数

如何在不基于数据 map 的情况下将图例添加到lets plot kotlin

如何注入返回通用列表的转换器?

为什么我的通用Kotlin函数中的这个转换未经判断?

创建包含 3 个相同项目的列表/使用返回类型重复

如何将glide显示的图像下载到设备存储中.Kotlin

将子元素放在一个列表中

为空数组添加值

这是什么 Kotlin 类型:(String..String?)

如何在 kotlin 的片段类中更改 ActionBar 标题?

如何处理 Kotlin 中的异常?

主机名不能为空

如何在MVVM架构中观察RecyclerView适配器中的LiveData?

Kotlin使用运行时断言进行空判断?

Kotlin:如何从另一个类访问字段?

Jetpack Compose 折叠工具栏

可以在函数参数中使用解构吗?

递归方法调用在 kotlin 中导致 StackOverFlowError 但在 java 中没有