Сортировать массив по алфавиту, используя Kotlin - PullRequest
0 голосов
/ 17 ноября 2018

Я делаю пусковую установку для своего телефона, и мне нужно отсортировать приложения по алфавиту.

 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

Ответы [ 2 ]

0 голосов
/ 17 ноября 2018

Идиоматическим способом является использование метода расширения sortedBy для List, если вы хотите отсортировать копию списка. Или используйте расширение sortBy на MutableList, если вы хотите выполнить сортировку на месте без копии. 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() }

и если держать в качестве ArrayList, то же самое, но не идиоматично, иметь ссылку непосредственно на этот конкретный тип.

// 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() }

Обратите внимание на toString() на элементе label: CharSequence. Вы должны быть осторожны при сортировке ссылки типа CharSequence, так как она не определена, каково ее поведение при сортировке (см .: https://docs.oracle.com/javase/7/docs/api/java/lang/CharSequence.html)

Этот интерфейс не уточняет общие контракты методов equals и hashCode. Поэтому результат сравнения двух объектов, реализующих CharSequence, вообще не определен.

Если CharSequence уже является String (вероятно, есть), то нет никакого вреда в вызове toString(), поскольку он просто возвращает себя.

Также имейте в виду, что обнуляемый CharSequence также должен быть обработан, и вам нужно решить, где вы хотите нули: в начале или в конце списка. Я думаю, что по умолчанию они идут на старт.

<Ч />

Другие примечания о вашем коде в вопросе:

Используйте интерфейс List или MutableList вместо конкретного класса, чтобы ссылаться на тип, и используйте методы из Kotlin stdlib для выполнения действий над списком. Также используйте val вместо var для ссылок, которые не изменятся ( означает, что он всегда будет указывать на один и тот же список независимо от того, может ли содержимое списка измениться ).

Ваше большое 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)
    }
}

проще:

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

Вам следует просмотреть стандартную библиотеку , чтобы получить представление о том, что доступно, и расширить свой инструментарий на будущее.

0 голосов
/ 17 ноября 2018

Вы можете сделать это, используя Collections.sort() и либо собственную реализацию Comparator<AppInfo>, которая работает на AppInfo.label, либо заставив класс AppInfo реализовать интерфейс Comparable и реализовать метод compareTo способом, который просто сравнивает поля метки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...