Object中的equals()方法默认是按地址比较,而不按内容进行比较,

  1. public boolean equals(Object obj) {
  2. return (this == obj);
  3. }

在String中覆写了Object中的equals方法,以用于判断字符串是否相同,

  1. public boolean equals(Object anObject) {
  2. if (this == anObject) {
  3. return true;
  4. }
  5. if (anObject instanceof String) {
  6. String anotherString = (String) anObject;
  7. int n = value.length;
  8. if (n == anotherString.value.length) {
  9. char v1[] = value;
  10. char v2[] = anotherString.value;
  11. int i = 0;
  12. while (n-- != 0) {
  13. if (v1[i] != v2[i])
  14. return false;
  15. i++;
  16. }
  17. return true;
  18. }
  19. }
  20. return false;
  21. }

"上帝"Object中equals方法可以被子类重写,然后多态调用,当我们要自定义对象比较时一般要覆写equals方法,比如有Person对象,同姓名同年龄,视为同一个对象,

  1. public boolean equals(Object obj)
  2. {
  3. if(!(obj instanceof Person))
  4.          return false;
  5. Person p = (Person)obj;
  6. return this.name.equals(p.name) && this.age == p.age;
  7. }

List集合判断元素是否相同,依据是元素的equals方法。

如果要将自定义对象存入到HashSet中,则要覆写hashCode()和equals():

  1.     public int hashCode()
  2. {
  3. //System.out.println(this.name+"....hashCode");
  4. return name.hashCode()+age*11;
  5. }
  6.  
  7. public boolean equals(Object obj)
  8. {
  9. if(!(obj instanceof Person))
  10. return false;
  11. Person p = (Person)obj;
  12.  
  13. //System.out.println(this.name+"....equals..."+p.name);
  14. return this.name.equals(p.name) && this.age==p.age;
  15. }

HashSet:底层数据结构是哈希表。是线程不安全的。不同步。
            HashSet是如何保证元素唯一性的呢?是通过元素的两个方法,hashCode和equals来完成。
            如果元素的HashCode值相同,才会判断equals是否为true。
            如果元素的hashcode值不同,不会调用equals。
注意,对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashcode和equals方法。


自定义比较器:

当元素自身不具备比较性,或者具备的比较性不是所需要的,这时需要让容器自身具备比较性。
当两种排序都存在时,以比较器为主。
方式1:定义一个类,实现Comparable接口,覆盖compareTo方法。

  1. class Student implements Comparable//该接口强制让学生具备比较性。
  2. {
  3. private String name;
  4. private int age;
  5.  
  6. Student(String name,int age)
  7. {
  8. this.name = name;
  9. this.age = age;
  10. }
  11.  
  12. //先按年龄从小到大排序,如果年龄相同,再按名字
  13. public int compareTo(Object obj)
  14. {
  15. if(!(obj instanceof Student))
  16. throw new RuntimeException("不是学生对象");
  17. Student s = (Student)obj;
  18.  
  19. if(this.age>s.age)
  20. return 1;
  21. if(this.age==s.age)
  22. {
  23. return this.name.compareTo(s.name);
  24. }
  25. return -1;
  26. }
  27.  
  28. public String getName()
  29. {
  30. return name;
  31. }
  32. public int getAge()
  33. {
  34. return age;
  35. }
  36. }
  37.  
  38. class Test
  39. {
  40. public static void main(String[] args)
  41. {
  42. TreeSet ts = new TreeSet(new Mycompare());
  43.  
  44. ts.add(new Student("lisi02",22));
  45. ts.add(new Student("lisi02",21));
  46. ts.add(new Student("lisi007",20));
  47. ts.add(new Student("lisi09",19));
  48. ts.add(new Student("lisi06",18));
  49. ts.add(new Student("lisi06",18));
  50. ts.add(new Student("lisi007",29));
  51.  
  52. Iterator it = ts.iterator();
  53. while(it.hasNext())
  54. {
  55. Student stu = (Student)it.next();
  56. System.out.println(stu.getName()+"..."+stu.getAge());
  57. }
  58. }
  59. }

方式2:定义一个类,还要再自定义一个比较器实现Comparator接口,覆盖compare方法。

定义了比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。

  1. class Student
  2. {
  3. private String name;
  4. private int age;
  5.  
  6. Student(String name,int age)
  7. {
  8. this.name = name;
  9. this.age = age;
  10. }
  11.  
  12. public String getName()
  13. {
  14. return name;
  15. }
  16. public int getAge()
  17. {
  18. return age;
  19. }
  20. }
  21.  
  22. //自定义比较器:先按名字来排序,如果名字相同再按年龄
  23. class Mycompare implements Comparator
  24. {
  25. public int compare(Object o1,Object o2)
  26. {
  27. Student s1 = (Student)o1;
  28. Student s2 = (Student)o2;
  29.  
  30. int num = s1.getName().compareTo(s2.getName());
  31. if (num == 0)
  32. return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
  33. return num;
  34. }
  35. }
  36. class Test
  37. {
  38. public static void main(String[] args)
  39. {
  40. TreeSet<Student> ts = new TreeSet<Student>(new Mycompare());
  41.  
  42. ts.add(new Student("lisi02",22));
  43. ts.add(new Student("lisi02",21));
  44. ts.add(new Student("lisi007",20));
  45. ts.add(new Student("lisi09",19));
  46. ts.add(new Student("lisi06",18));
  47. ts.add(new Student("lisi06",18));
  48. ts.add(new Student("lisi007",29));
  49.  
  50. for (Iterator<Student> it = ts.iterator();it.hasNext() ; )
  51. {
  52. Student stu = it.next();
  53. System.out.println(stu.getName()+".."+stu.getAge());
  54. }
  55. }
  56. }

Java中的equals方法和自定义比较器的更多相关文章

  1. 关于Java中的equals方法

    关于Java中的equals方法 欢迎转载,但是请填写本人的博客园原址https://www.cnblogs.com/JNovice/p/9347099.html 一.什么是equals方法 equa ...

  2. 【转】彻底弄懂Java中的equals()方法以及与"=="的区别

    彻底弄懂Java中的equals()方法以及与"=="的区别 一.问题描述:今天在用Java实现需求的时候,发现equals()和“==”的功能傻傻分不清,导致结果产生巨大的偏差. ...

  3. 一文搞懂--Java中重写equals方法为什么要重写hashcode方法?

    Java中重写equals方法为什么要重写hashcode方法? 直接看下面的例子: 首先我们只重写equals()方法 public class Test { public static void ...

  4. Java中“==”与equals方法的区别

    1. 用“==”比较两个变量,如果两个变量是基本类型变量,且都是数值类,则值相等就返回true 如果两个变量是引用型变量,则两个对象的地址一样,即指向同一个对象,则返回true 2.equals:St ...

  5. JAVA中复写equals方法

    在JAVA中“==”用于比较两个引用对象的地址是否相同.但是如果我们想比较两个对象的内容是否相同,通常会覆写equals方法.equals方法用来比较两个对象的内容是否相等. package org. ...

  6. JAVA中“==”与equals()方法区别

    equals 方法是 java.lang.Object 类的方法 有两种用法说明: ()对于字符串变量来说,使用"=="和"equals()"方法比较字符串时, ...

  7. 如何在Java中避免equals方法的隐藏陷阱

    摘要 本文描述重载equals方法的技术,这种技术即使是具现类的子类增加了字段也能保证equal语义的正确性. 在<Effective Java>的第8项中,Josh Bloch描述了当继 ...

  8. 如何重写Java中的equals方法

    Java中,只有8种基本类型不是对象,例如:4种整形类型(byte, short, int,long),2种浮点类型(flout, double),boolean, char不是对象,其他的所有类型, ...

  9. java中的equals方法

    这个方法首先比较的是两个对象的地址是否相同,如果相同直接返回true, 否则, (1)如果是string类型的先比较是否是string类型,是的话,再比较是否长度相同,相同的话再比较,每个字符是否相同 ...

随机推荐

  1. 洛谷 P1064 金明的预算方案【DP/01背包-方案数】

    题目背景 uim神犇拿到了uoi的ra(镭牌)后,立刻拉着基友小A到了一家--餐馆,很低端的那种. uim指着墙上的价目表(太低级了没有菜单),说:"随便点". 题目描述 不过ui ...

  2. Codeforces Round #191 (Div. 2) A. Flipping Game【*枚举/DP/每次操作可将区间[i,j](1=<i<=j<=n)内牌的状态翻转(即0变1,1变0),求一次翻转操作后,1的个数尽量多】

    A. Flipping Game     time limit per test 1 second memory limit per test 256 megabytes input standard ...

  3. Codeforces Round #505 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final) -B C(GCD,最长连续交替序列)

    B. Weakened Common Divisor time limit per test 1.5 seconds memory limit per test 256 megabytes input ...

  4. HNOI2004 郁闷的出纳员(Splay)

    郁闷的出纳员 OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的 ...

  5. android利用adb shell查看activity的栈

    Android中怎么查看应用的activity栈? 1. 进入adb shell 2.可以直接输入dumpsys ,可以查看device的一些信息如 3.也可以直接输入 dumpsys activit ...

  6. Uva 11077 Find the Permutation

    可以发现最优的方案就是一个循环节内互换. 所以一个有n个元素,c个循环节的置换的交换次数(最少)是n-c. 然后就可以递推了,把i插入到前i-1个元素构成的置换中,要么新成立一个循环,要么加入到之前的 ...

  7. [COCI2015]ZMIJA

    题目大意: 一个$n\times m(n,m\leq1000)$的格子中有若干金币,从左下角出发,每一步可以进行如下操作: 1.向当前方向前进一格: 2.向上移动一步,并调转当前方向. 一开始的方向是 ...

  8. nginx的proxy_set_header

    nginx配置的server段: listen 8888; server_name wyc.com; location /user { proxy_set_header HOST fake.com; ...

  9. iOS isa 浅析

    看见一到面试题讲述一下Objective-C中的isa?完全没听说过,打算小研究一下. 参考:http://blog.sina.com.cn/s/blog_7a2ffd5c01010nme.html ...

  10. IO模型同步与异步阻塞与非阻塞的区别

    同步异步的区别 关注点:同步和异步关注的是消息通信机制 同步:所谓同步,就是在发出一个*调用*时,在没有得到结果之前,该*调用*就不返回.但是一旦调用返回,就得到返回值了.换句话说,就是由*调用者*主 ...