Сортировка массива по алфавиту с помощью Kotlin

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

 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

используйте Collections.sort (your_list), это даст вам отсортированный список

pratik vekariya 17.11.2018 14:02

@pratikvekariya, ваш комментарий неверен, это список классов, которые не реализуют Comparable и, следовательно, не имеют естественного порядка, ваш метод не работает, и, кроме того, он не является идиоматическим для Kotlin.

Jayson Minard 17.11.2018 19:15

Дэвид, есть ответ на ваш вопрос или вы ищете что-то еще?

Jayson Minard 19.11.2018 05:44

Да, это. (:

David Wenzel 01.01.2019 18:11
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
14
4
15 977
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

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

Этот ответ неполный, потому что это более сложный вопрос. Во-первых, типы данных, доступные для сортировки, не подлежат сортировке (CharSequence), и это не идиоматический тип Kotlin: создавать Comparator только для одноразовой сортировки или снова добавлять Comparable в класс для одноразовой сортировки. Также необходимо учитывать нулевую обработку, поскольку все типы в классе допускают нулевое значение.

Jayson Minard 17.11.2018 19:34
Ответ принят как подходящий

Идиоматический способ - использовать метод расширения 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)

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() не причинит вреда, поскольку он просто возвращает себя.

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


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

Используйте интерфейс 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)
}

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

Спасибо! Это действительно помогает, когда я нахожу что-то в списке.

David Wenzel 23.12.2018 22:09
class CustomClass {
    var id: String = ""
    var name: String = ""
}

fun sortAlphabetically(arrayList: ArrayList< CustomClass >): ArrayList< CustomClass >{
        var returnList: ArrayList< CustomClass > = arrayListOf()
        var list = arrayList as MutableList< CustomClass >
        list.sortWith(Comparator { o1: CustomClass, o2: CustomClass ->
            o1.name.compareTo(o2.name)
        })
        returnList = list as ArrayList< CustomClass >
        return returnList
    }

Другие вопросы по теме