【问题标题】:Usefulness of compareTo when comparing different case [closed]compareTo 在比较不同情况时的用处[关闭]
【发布时间】:2021-09-26 23:07:27
【问题描述】:

String 类实现了Comparable 接口,我们可以看到结果是两个字符串之间的字典差异,这是有道理的:

String s1 = "AB";
String s2 = "AF";
  
System.out.println(s1.compareTo(s2)); 

将输出-4,而如果我们切换参数输出4

我不明白的是与不同情况的字符串的比较,

String s1 = "Ac";
String s2 = "AD";
  
System.out.println(s1.compareTo(s2)); 

这将输出 31 它只是根据 ASCII 表告诉我字符串中前两个不同字符之间的区别,它告诉我 "Ac" 大于 "AD" 31

现在,我知道通过自定义比较器可以轻松解决此问题,无论如何我看不出默认比较器给出的这个结果有什么用处,它的目的是什么?

当我比较字符串时,我通常只想知道它们是否相等,如果一个大于另一个,不管它们是大写还是小写,我通常只想知道它们是否相等,默认情况下比较不区分大小写不是更好吗?

【问题讨论】:

  • 情况并没有什么不同:'B' - 'F' 是 -4,'c'-'D' 是 31,但这只是一个实现细节。 compareTo() 方法仅根据结果的符号定义(小于零、零、大于零)
  • 更直观的区分大小写的compareTo 会如何表现?
  • @anastaciu 那么您是否认为equals 默认情况下也应该不区分大小写?
  • 考虑到不区分大小写的复杂性,compareToequals 的默认设置很简单且区分大小写,这是一件好事。请参阅docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/… 以了解我在说什么。那就看看它的源码吧。

标签: java string comparator


【解决方案1】:

compareTo 返回的实际数字对于Comparable 的合同而言并不重要。它不是为了“有用”,而是为了它的标志。

唯一相关的是值与零的比较(> 0== 0< 0)。换句话说,不要指望返回的实际数量,它可能会随着实现版本而改变(不违反合同)。老实说,如果我发现自己使用了 Comparable 合同之外的返回值,我肯定我有代码味道。

如果你想要总是相同的数字,你可以使用结果的符号:

System.out.println(Math.signum(s1.compareTo(s2))) //cast if needed

这将始终产生-1.00.01.0,具体取决于结果,您可以依赖它。

【讨论】:

  • 是的,没错,我们只是用它来知道它们是否相等,以及更大的那个是什么,尽管不太常见。这就是为什么我认为让 compareTo 不区分大小写会很有用。
  • 非常感谢您的回答,两个答案都很好,我必须选择一个,所以我像往常一样选择了票数较高的一个,对此感到抱歉。
  • @anastaciu 绝对没有什么可遗憾的。只有一个被接受的答案,我看到你有一种客观的方式来选择:-)
【解决方案2】:

默认区分大小写的比较器 如果您只想要这种行为,则很有用:两个字符串之间区分大小写的比较。事实上,Ac 在字典上大于AD。如果您想要不区分大小写的比较,则使用String#compareToIgnoreCase,例如:

String s1 = "Ac";
String s2 = "AD";

System.out.println(s1.compareToIgnoreCase(s2));  // -1 => Ac < AD, ignoring case

【讨论】:

  • 我明白了,这还是有点违反直觉。不应该反过来,默认比较不区分大小写吗?
  • @anastaciu Comparable 的实现理想地“与equals 一致”。而"A" 绝对不等于"a"。不区分大小写会更违反直觉。
  • @Slaw 这是一个公平的观点。
猜你喜欢
  • 1970-01-01
  • 2016-11-05
  • 1970-01-01
  • 2019-06-03
  • 2020-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多