聚沙成塔、水滴石穿

转载请注明出处:

1、equals()方法

equals()方法定义在Object类内并进行了简单的实现,如下:

public boolean equals(Object obj) {return (this == obj); }

比较两个原始类型比较的是内容,而如果比较引用类型的话,可以看到是通过==符号来比较的,所以比较的是引用地址,如果要自定义比较规则的话,可以覆写自己的equals()方法。String 、Math、还有Integer、Double等封装类重写了Object中的equals()方法,让它不再比较引用,而是比较对象中实际包含内容。在编写equals()方法时需要遵守一些规定:

看一下String类的equals()实现,如下:

public boolean equals(Object anObject) {if (this == anObject) {// 反射性return true;}if (anObject instanceof String) { // 只有同类型的才能比较String anotherString = (String) anObject;int n = value.length;if (n == anotherString.value.length) {char v1[] = value;char v2[] = anotherString.value;int i = 0;while (n– != 0) {if (v1[i] != v2[i])return false;i++;}return true; // 返回true时,表示长度相等,且字符序列中含有的字符相等}}return false;}

当我们自己要重写equals()方法进行内容的比较时,可以遵守以下几点:

(1)使用instanceof操作符检查“实参是否为正确的类型”。

(2)对于类中的每一个“关键域”,检查实参中的域与当前对象中对应的域值。

无论是Arrays工具类中提供了各种常用数据类型的比较方法,还是对象引用域的equals()方法,其实最终都是转换为float、String等的类型,然后遵照前三个规则来进行比较的,而这些类型的比较方法已经得到了实现。来看一下Arrays类中双精度浮点数的比较:

public static boolean equals(double[] a, double[] a2) {if (a==a2)return true;if (a==null || a2==null)return false;int length = a.length;if (a2.length != length)return false;for (int i=0; i<length; i++)if (Double.doubleToLongBits(a[i])!=Double.doubleToLongBits(a2[i])) // 调用Double类中的方法进行比较return false;return true;}有兴趣的可以自己去看其他的实现源代码。

一般来说,如果你要把一个类的对象放入集合中,那么通常要为其重写equals()方法,让他们比较地址值而不是内容值。特别地,如果要把你的类的对象放入散列中,那么还要重写hashCode()方法;要放到有序集合中,,还要重写compareTo()方法。 如上说到的在容器实现的部分中要进行详细的讲解,这里不再做过多的解释。

有兴趣的可以去看集合的实现:传送门:Java 7集合源码

2、Comparable接口

一个类实现了 Camparable 接口表明这个类的对象之间是可以相互比较的。如果用数学语言描述的话就是这个类的对象组成的集合中存在一个全序。这样,这个类对象组成的集合就可以使用 Sort 方法排序了。

这个接口定义在java.lang包下,其源代码如下:

public interface Comparable<T> {public int compareTo(T o);}

这个接口支持泛型,在实现compareTo()方法时可限定具体的比较类型。下面来举一个例子,如下:

public class PersonBean implements Comparable<PersonBean> {public PersonBean(int age, String name) {this.age = age;// 引用类型this.name = name; // 基本类型}int age = 0;String name = "";public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}// 覆写equals和hashCode方法public boolean equals(Object o) {if (!(o instanceof PersonBean)) {return false;}PersonBean p = (PersonBean) o;return (age == p.age) && (name.equals(p.name));}public int hashCode() {int result = 17;result = 31 * result + age;result = 31 * result + name.hashCode();return result;}public String toString() {return (age + "{" + name + "}");}public int compareTo(PersonBean person) {int cop = age – person.getAge();if (cop != 0)return cop;elsereturn name.compareTo(person.name);}}

如果两个人的年龄相同,则通过字符串类中的compareTo()方法进行比较。来看String类的定义如下:

public final class String implements java.io.Serializable, Comparable<String>, CharSequence 可以看到实现了Comparable接口并且还实现了接口中定义的方法,源代码如下: public int compareTo(String anotherString) {int len1 = value.length;int len2 = anotherString.value.length;int lim = Math.min(len1, len2); // 返回len1和len2中长度较小的一个char v1[] = value;char v2[] = anotherString.value;int k = 0;while (k < lim) {// 根据字符序列中所含字符的Unicode编码值来比较char c1 = v1[k];char c2 = v2[k];if (c1 != c2) {return c1 – c2;}k++;}return len1 – len2;// 如果两个字符串的k个字符相等,则长度较小的在前}

字符串最后都是转换为字符数组进行比较的。

将代码放到List中进行排序:

public void compare() {List<PersonBean> list = new ArrayList<PersonBean>();list.add(new PersonBean(20, "Tom"));list.add(new PersonBean(20, "Jeff"));list.add(new PersonBean(30, "Mary"));list.add(new PersonBean(20, "Ada"));list.add(new PersonBean(61, "Peter"));list.add(new PersonBean(20, "Bush"));// 对List进行排序Collections.sort(list);for(int i=0;i<list.size();i++){System.out.println(list.get(i));}}public static void main(String[] args) {TestComparable tc = new TestComparable();tc.compare();}

或者也可以将代码放到Array数组中进行排序:

运行如上的代码:

『 不可能 』只存在於蠢人的字典里

聚沙成塔、水滴石穿

相关文章:

你感兴趣的文章:

标签云: