【问题标题】:How to sort objects with strings that contains number and include language sort?如何使用包含数字并包含语言排序的字符串对对象进行排序?
【发布时间】:2021-04-28 10:25:54
【问题描述】:

我需要使用包含数字并包含语言排序的字符串对对象进行排序 我的对象包括文件、字符串文件名、字符串 isFolder。

当我对文件夹中的文件列表进行排序时

名单:

  1. “默认语言的文件名”
  2. “文件名1”
  3. “文件名10”
  4. “文件名11”
  5. “文件名2”
  6. “文件名20”

我怎样才能像这样对它们进行排序:

  1. “默认语言的文件名”
  2. “文件名1”
  3. “文件名2”
  4. “文件名10”
  5. “文件名11”
  6. “文件名20”

我的代码:

final Collator collator = Collator.getInstance(Locale.getDefault());
// listJFiles = ArrayList of my objects called "JFile"
listJFiles.sort((o1, o2) -> collator.compare(o1.isFolder + o1.fileName, o2.isFolder + o2.fileName));

(这个没用 - How to sort by two fields in Java? 因为我还需要按语言排序,而且我不知道如何将它与按语言排序的代码结合起来)

【问题讨论】:

标签: android sorting arraylist


【解决方案1】:

首先,我想写几句话来解释观察到的行为。这是正确的和预期的。字符串对象根据 ASCII 表 (http://www.asciitable.com/) 中字符的序号逐个字符进行比较。如果两个字符串具有相同的开头,则较长的字符串被认为较大。这就是为什么“文件名 10”大于“文件名 1”而“文件名 2”大于“文件名 10”的原因。

您想要实现的行为需要在比较机制中再包含一个因素:将数字考虑在内并使用算术规则进行比较。

我想你发布的例子是部分和简单的:没有数字或只有一个数字,它总是放在字符串的末尾。而一个完整的问题可能意味着一个字符串可能包含位于任何位置的任意数量的数字。

我会给你一个解决这个问题的可能方法,它解决了简单的情况(你描述的那个):

data class Item(val text: String)
data class SplitItem(val text: String, val number: Int?)

fun SplitItem.toItem() = Item(text + (number?.let { " $it" } ?: ""))

fun main() {
    val items = listOf(
        Item("file name with default language"),
        Item("file name 1"),
        Item("file name 10"),
        Item("file name 11"),
        Item("file name 2"),
        Item("file name 20")
    ).shuffled()

    val splitItems = items.map {
        val split = it.text.split(' ')

        try {
            val number = Integer.parseInt(split.last())
            SplitItem(
                text = split.dropLast(1).joinToString(separator = " "),
                number = number
            )
        } catch (e: NumberFormatException) {
            SplitItem(
                text = it.text,
                number = null
            )
        }
    }

    val sortedItems = splitItems.sortedWith { o1, o2 ->
        val n = compareValues(o1.number, o2.number)
        val t = compareValues(o1.text, o2.text)
        compareValues(n, t)
    }

    sortedItems
        .map { it.toItem() }
        .forEach { println(it) }

}

产生下一个输出:

Item(text=file name with default language)
Item(text=file name 1)
Item(text=file name 2)
Item(text=file name 10)
Item(text=file name 11)
Item(text=file name 20)

为了解决全部问题,我建议您改进这种方法。

【讨论】:

  • 我在 java 很抱歉...(我不知道 kotlin)真的很抱歉,谢谢您的尝试...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-04
  • 2020-03-21
  • 2020-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多