如何对包含数字的 String 集合进行排序?
我有一个字符串向量,其中包含如下数据:
5:34、5:38、17:21、22:11、...
如果我尝试使用 Collections.sort( ... ); 合并它,它将显示如下:
17:21、22:11、5:34、5:38
实际上我希望它看起来像这样:
5:34、5:38、17:21、22:11
所以我想根据冒号“:”之前的数字对元素进行排序,那么如果某些元素在“:”之前有相同的数字,则根据“:”后的数字。
最简单的方法是什么?
I have a String Vector that contains data like this :
5:34, 5:38, 17:21, 22:11, ...
If i try to merge this using Collections.sort( ... ); it will appear like this :
17:21, 22:11, 5:34, 5:38
Actually i want it to appear like this :
5:34, 5:38, 17:21, 22:11
So i want to sort the elements according to the number before the colon ":" then if some elements have the same number before ":" then sort them according to the number after the ":".
What is the simplest way to do this ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
执行此操作的正确方法是不将非字符串值存储为字符串。
集合中的数据具有一定的结构和规则,不能是任意字符串。因此,您不应使用
String
数据类型。让我们定义一个名为
TwoNumbers
的类型(因为我不知道该类型应该代表什么,即使我能猜到):compareTo
方法作为Comparable
接口:它定义了该类型的对象如何订购了。我使用了
final
字段(并且不提供设置器),因为该类实现了这样,您就可以直接对数据进行排序,而无需额外的
比较器
,并且不需要在整个程序中分发所有“拆分和解析”代码。相反,您有一个单个类负责处理该特定格式,并且所有其他代码段都可以使用它。The correct way to do this is to not store non-string values as strings.
The data in your collection has some structure and rules and can't be any arbitrary string. Therefore you should not use the
String
data type.Let's define a type called
TwoNumbers
(because I don't know what the type should represent, even if I could guess):The
compareTo
method exists as the implementation of theComparable
interface: it defines how objects of this type are ordered.I've used the
final
fields (and don't provide setters), because the class implements immutable objects.This way you can directly sort your data without an additional
Comparator
and don't need to distribute all that "split and parse" code all over your program. Instead you have a single class that's responsible for handling that specific format and all the other pieces of code can just use that.这是非常低效的,但它应该可以完成工作。
(提示:如果这是我的代码,我会优化它以使用子字符串而不是 String.split(),但我太懒了)
This is horribly inefficient, but it should do the job.
(Hint: if it were my code, I'd optimize it to use substrings instead of String.split(), but I'm too lazy)
您可以创建一个自定义
Comparator
来拆分String
并将其解析为两个整数,或创建一个定制类来表示每个String
并将其存储在Collection
中。我喜欢后一种方法,因为您只需要拆分/解析字符串一次的开销;例如,那么这只是在您的
Collection
中存储一些Data
对象的情况;例如,还有一件事 - 您提到您正在使用
Vector
。您应该尽量避免使用Vector
/Hashtable
,因为它们已被引入的List
/Map
取代作为 JDK 1.2 中集合框架的一部分。You could either create a custom
Comparator
to split theString
and parse it into two ints, or create a bespoke class to represent eachString
and store that in theCollection
instead. I favour the latter approach as you only incur the overhead of splitting / parsing the String once; e.g.Then it's simply a case of storing some
Data
objects in yourCollection
; e.g.One more thing - You mention you're using a
Vector
. You should try to avoid usingVector
/Hashtable
as these have been superseded byList
/Map
, which were introduced as part of the Collections Framework in JDK 1.2.创建一个 java.util.Comparator 并将其提供给 sort 方法。
Create a
java.util.Comparator
and provide it to thesort
method.实现您自己的
Comparator
类,该类比较两个值并调用Collections.sort(List list, Comparator c)
。Implement your own
Comparator
class that compares two values and callCollections.sort(List list, Comparator c)
.实现您自己的 Comparator 并将其作为 Colelctions.sort 方法的第二个参数。
Implement your own Comparator and give it as second argument to the Colelctions.sort method.
通常,Java 中的对象(包括 Collections)会与其默认的 hashCode() 和 equals() 方法进行比较。对于内置对象和数据类型(如 String、Integet 等),hashCode() 是在内部计算的,因此它们的使用受到 JLS(Java 语言规范)的保证。
由于我们不能总是依赖于默认/内置对象,并且我们需要处理我们自己的自定义对象(如 Employee、Customer 等),因此我们应该重写 hashCode() 和 equals() 方法,因此我们可以根据自定义类的对象的“最佳”相等性来提供真/假。
类似地,sort()涉及一个比较行为,它确实需要一个Comparator(它是一个实现Comparator接口的类,并重写了compare方法)。您还应该重写比较方法,该方法需要比较两个对象并返回结果(0 表示相等,1 表示第一个对象大于第二个对象,2 表示情况 1 相反)。
现在,您的数据应该以不同的方式处理,这与正常的比较完全不同。您需要将数据分成两部分(可以使用拆分方法),然后可以对两部分进行单独比较(第一部分在冒号之前,第二部分在冒号之后)。
最后,您应该向排序方法提供此自定义比较器的实例,该实例最终将为您的自定义数据进行自定义排序:)
Generally, objects in Java (including Collections) are compared with their default hashCode() and equals() method. For the built in objects and data types (like String, Integet etc.,) the hashCode() is computed internally and hence they are used as guaranteed by the JLS (Java Language Specification).
As we can't always be dependent upon the default/built in objects and we need to deal with our own custom objects (like Employee, Customer etc.,), we should have to override hashCode() and equals() method, so that we can provide the true/false according to the "BEST" equality of the objects of our custom classes.
Similary, sort() involves a comparison act that indeed needs a Comparator (which is a class implementing the Comparator interface with an overridden method of compare method). You should also override the compare method that takes two Objects to be compared and returns a result (0 for equal, 1 for the 1st object being greater than the second, 2 for the reverse of case 1).
Now, you data should be dealt in a different way which is quite away from the normal comparsion. You need to split the data into two parts (using a split method you can do) and then you can do the individual comparison on the two parats (first part before the colon, second part after the colon).
Finally, you should provide an instance of this custom comparator to the sort method, that will eventually do the custom sorting for your custom data :)
我认为这很简单:
I think this is pretty simple:
刚刚发现这篇(相当旧的)帖子,答案并没有完全解决我的问题。我需要一个更通用的解决方案,因为这些值是用户输入,并且诸如“abc 1 a 12”和“abc 1 a 1”之类的内容应该按照包含的数字的顺序进行排序。所以我写了以下比较器:
而函数 splitNumeric 定义如下:
代码将按
如下方式对字符串进行排序:
享受:)
Just found this (quite old) post and the answers didn't quite solve the problem I have. I needed a more generic solution, as the values were user inputs and something like "abc 1 a 12" and "abc 1 a 1" should be sorted in order of the contained number(s). So I wrote the following Comparator:
While the function splitNumeric is defined as follows:
The code will sort Strings
as follows:
Enjoy :)