|
什么是选择问题? 选择问题,是假设一组 N 个数,要确定其中第 K 个最大值者。比如 A 与 B 对象需要哪个更大?又比如:要考虑从一些数组中找出最大项?
解决选择问题,需要对象有个能力,即比较任意两个对象,并确定哪个大,哪个小或者相等。找出最大项问题的解决方法,只要依次用对象的比较(Comparable)能力,循环对象列表,一次就能解决。
那么 JDK 源码如何实现比较(Comparable)能力的呢?
java.lang.Comparable 接口
enter image description here
Comparable 接口,从 JDK 1.2 版本就有了,历史算悠久。Comparable 接口强制了实现类对象列表的排序。其排序称为自然顺序,其 compareTo 方法,称为自然比较法。
该接口只有一个方法 public int compareTo(T o); ,可以看出:
入参 T o :实现该接口类,传入对应的要被比较的对象;
返回值 int:正数、负数和 0 ,代表大于、小于和等于。
对象的集合列表(Collection List)或者数组(arrays) ,也有对应的工具类可以方便的使用:
java.util.Collections#sort(List) 列表排序
java.util.Arrays#sort(Object[]) 数组排序
那 String 对象如何被比较的?
String 源码中的算法
String 源码中可以看到 String JDK 1.0 就有了。那么应该是 JDK 1.2 的时候,String 类实现了 Comparable 接口,并且传入需要被比较的对象是 String。对象如图:
enter image description here
String 是一个 final 类,无法从 String 扩展新的类。从 114 行,可以看出字符串的存储结构是字符(Char)数组。先可以看看一个字符串比较案例,代码如下:
/**
* 字符串比较案例
*
* Created by bysocket @ bysocket.com on 19/5/10.
*/
public class StringComparisonDemo {
public static void main(String[] args) {
String foo = "ABC";
// 前面和后面每个字符完全一样,返回 0
String bar01 = "ABC";
System.out.println(foo.compareTo(bar01));
// 前面每个字符完全一样,返回:后面就是字符串长度差
String bar02 = "ABCD";
String bar03 = "ABCDE";
System.out.println(foo.compareTo(bar02)); // -1 (前面相等,foo 长度小 1)
System.out.println(foo.compareTo(bar03)); // -2 (前面相等,foo 长度小 2)
// 前面每个字符不完全一样,返回:出现不一样的字符 ASCII 差
String bar04 = "ABD";
String bar05 = "aABCD";
System.out.println(foo.compareTo(bar04)); // -1 (foo 的 'C' 字符 ASCII 码值为 67,bar04 的 'D' 字符 ASCII 码值为 68。返回 67 - 68 = -1)
System.out.println(foo.compareTo(bar05)); // -32 (foo 的 'A' 字符 ASCII 码值为 65,bar04 的 'a' 字符 ASCII 码值为 97。返回 65 - 97 = -32)
String bysocket01 = "泥瓦匠";
String bysocket02 = "瓦匠";
System.out.println(bysocket01.compareTo(bysocket02));// -2049 (泥 和 瓦的 Unicode 差值)
}
}
|
|