按字符和长度排序字符串

在我的Android应用程序中,我尝试按1,2,3,4等排序总线路由标记。

为此,我正在使用这个

Collections.sort(directions, Comparator { lhs, rhs -> var obj1 = lhs.short_names.firstOrNull() ?: "" var obj2 = rhs.short_names.firstOrNull() ?: "" if (obj1 === obj2) { obj1 = lhs.headsigns.firstOrNull() ?: "" obj2 = rhs.headsigns.firstOrNull() ?: "" if (obj1 === obj2) { return@Comparator 0 } obj1.compareTo(obj2) } else { obj1.compareTo(obj2) } 

我所遇到的问题是这样的,但会遇到1,2,3,31,3,4,5

我应该如何改变这个来获得正确的顺序。

如果你只需要一个简单的数字比较,你可以这样做。

 directions.sortWith(Comparator { lhs, rhs -> val i1 = lhs.toInt() val i2 = rhs.toInt() when { i1 < i2 -> -1 i1 > i2 -> 1 else -> 0 } }) 

正如热键所指出的,上面的代码可以被几乎相同的实现替代,看起来更简单。

 directions.sortBy { it.toInt() } 

这种算法的通用版本被称为alphanum排序,在这里详细描述。 我做了这个算法的Kotlin端口,你可以使用它。 这比你所需要的更复杂,但它会解决你的问题。

 class AlphanumComparator : Comparator<String> { override fun compare(s1: String, s2: String): Int { var thisMarker = 0 var thatMarker = 0 val s1Length = s1.length val s2Length = s2.length while (thisMarker < s1Length && thatMarker < s2Length) { val thisChunk = getChunk(s1, s1Length, thisMarker) thisMarker += thisChunk.length val thatChunk = getChunk(s2, s2Length, thatMarker) thatMarker += thatChunk.length // If both chunks contain numeric characters, sort them numerically. var result: Int if (isDigit(thisChunk[0]) && isDigit(thatChunk[0])) { // Simple chunk comparison by length. val thisChunkLength = thisChunk.length result = thisChunkLength - thatChunk.length // If equal, the first different number counts. if (result == 0) { for (i in 0..thisChunkLength - 1) { result = thisChunk[i] - thatChunk[i] if (result != 0) { return result } } } } else { result = thisChunk.compareTo(thatChunk) } if (result != 0) { return result } } return s1Length - s2Length } private fun getChunk(string: String, length: Int, marker: Int): String { var current = marker val chunk = StringBuilder() var c = string[current] chunk.append(c) current++ if (isDigit(c)) { while (current < length) { c = string[current] if (!isDigit(c)) { break } chunk.append(c) current++ } } else { while (current < length) { c = string[current] if (isDigit(c)) { break } chunk.append(c) current++ } } return chunk.toString() } private fun isDigit(ch: Char): Boolean { return '0' <= ch && ch <= '9' } } 

要使用此Comparator只需调用

 directions.sortWith(AlphanumComparator()) 

如果你不需要在Kotlin中编写代码,你可以在Dave Koelle的页面上获取原始的Java版本。 该算法的Kotlin版本也可以在GitHub上找到 。