A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© dicegame 中级黑马   /  2013-7-29 15:24  /  1400 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

  1. package qbb;

  2. import java.util.*;

  3. public class ArrayListTest {
  4.         public static ArrayList singleElement(ArrayList al) {
  5.                 ArrayList newAL = new ArrayList();
  6.                 Iterator it = al.iterator();
  7.                 while(it.hasNext()) {
  8.                         Object obj = it.next();
  9.                         if(!newAL.contains(obj)) {
  10.                                 newAL.add(obj);
  11.                         }
  12.                 }
  13.                 return newAL;
  14.         }
  15.         public static void main(String[] args) {
  16.                 ArrayList al = new ArrayList();
  17.                 al.add("java1");
  18.                 al.add("java2");
  19.                 al.add("java1");
  20.                 al.add("java2");
  21.                 al.add("java3");
  22.                 System.out.println(al);
  23.                 al = singleElement(al);
  24.                 System.out.println(al);
  25.         }
  26. }
复制代码
运行结果:
[java1, java2, java1, java2, java3]
[java1, java2, java3]
  1. package qbb;

  2. import java.util.*;

  3. class Person {
  4.         private String name;
  5.         private int age;
  6.         Person(String name,int age) {
  7.                 this.name = name;
  8.                 this.age = age;
  9.         }
  10.         public String getName() {
  11.                 return name;
  12.         }
  13.         public int getAge() {
  14.                 return age;
  15.         }
  16. }
  17. public class ArrayListTest2 {
  18.         public static ArrayList singleElement(ArrayList al) {
  19.                 ArrayList newAL = new ArrayList();
  20.                 Iterator it = al.iterator();
  21.                 while(it.hasNext()) {
  22.                         Object obj = it.next();
  23.                         if(!newAL.contains(obj)) {
  24.                                 newAL.add(obj);
  25.                         }
  26.                 }
  27.                 return newAL;
  28.         }
  29.         public static void main(String[] args) {
  30.                 ArrayList al = new ArrayList();
  31.                 al.add(new Person("Lisi01",30));
  32.                 al.add(new Person("Lisi02",32));
  33.                 al.add(new Person("Lisi02",32));
  34.                 al.add(new Person("Lisi03",33));
  35.                 al.add(new Person("Lisi04",33));
  36.                 al.add(new Person("Lisi04",33));
  37.                 System.out.println(al);
  38.                 al = singleElement(al);
  39.                 System.out.println(al);
  40.         }
  41. }
复制代码
运行结果:
[qbb.Person@1b60280, qbb.Person@5e55ab, qbb.Person@14a55f2, qbb.Person@15093f1, qbb.Person@120bf2c, qbb.Person@e6f7d2]
[qbb.Person@1b60280, qbb.Person@5e55ab, qbb.Person@14a55f2, qbb.Person@15093f1, qbb.Person@120bf2c, qbb.Person@e6f7d2]

调用的方法一样,
为什么第一个可以过滤重复,第二个却不可以呢?

评分

参与人数 1技术分 +1 收起 理由
杨兴庭 + 1

查看全部评分

7 个回复

倒序浏览
new Person("Lisi02",32) == new Person("Lisi02",32),楼主执行下这个语句,然后看看返回结果就应该知道是什么原因了

因为每一次new对象,都是在内存中生成一个对象实例,也就是说虽然他们的成员变量的值是相等的,但是在内存中是两个不同的对象元素。

楼主可以看下ArrayList集合的源代码,contains底层调用的是equals方法来判断元素是否相同,并确定集合是否包含被操作元素。

给楼主附上那段方法的源代码,很容易就理解了。
  1. public boolean contains(Object o) {
  2.         return indexOf(o) >= 0;
  3.     }

  4.     /**
  5.      * Returns the index of the first occurrence of the specified element
  6.      * in this list, or -1 if this list does not contain the element.
  7.      * More formally, returns the lowest index <tt>i</tt> such that
  8.      * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
  9.      * or -1 if there is no such index.
  10.      */
  11.     public int indexOf(Object o) {
  12.         if (o == null) {
  13.             for (int i = 0; i < size; i++)
  14.                 if (elementData[i]==null)
  15.                     return i;
  16.         } else {
  17.             for (int i = 0; i < size; i++)
  18.                 if (o.equals(elementData[i]))
  19.                     return i;
  20.         }
  21.         return -1;
  22.     }
复制代码

评分

参与人数 1技术分 +1 收起 理由
杨兴庭 + 1 赞一个!

查看全部评分

回复 使用道具 举报
本帖最后由 dicegame 于 2013-7-29 17:54 编辑
王磊 发表于 2013-7-29 15:45
new Person("Lisi02",32) == new Person("Lisi02",32),楼主执行下这个语句,然后看看返回结果就应该知道是 ...

谢谢啊,原来contails封装了底层的equals,
我试着查了下源代码ArrayList.java(JDK1.7),可找不到,
源代码怎么查呢?
C:\Users\Administrator\Desktop
回复 使用道具 举报
这是由于你没有改写Object的equals方法。你看,public boolean contains(Object o)的API中解释,如果此列表中包含指定的元素,则返回 true。更确切地讲,当且仅当此列表包含至少一个满足(o==null ? e==null : o.equals(e)) 的元素 e 时,则返回 true。蓝色字体部分说明,该方法背后也是调用equals方法来进行筛选。下面我把楼主Person类的equals方法改写了,运行结果如下:


  1. import java.util.*;

  2. class Person {
  3. private String name;
  4. private int age;
  5. Person(String name,int age) {
  6. this.name = name;
  7. this.age = age;
  8. }
  9. public String getName() {
  10. return name;
  11. }
  12. public int getAge() {
  13. return age;
  14. }
  15. //添加的内容,改写equals方法
  16. public boolean equals(Object obj) {
  17. if (obj.getClass() != getClass()) {
  18. return false;
  19. }
  20. if (this.name.equals(((Person)obj).name)) {
  21. return true;
  22. }
  23. return false;
  24. }
  25. //****************************************************************//
  26. }
  27. public class ArrayListTest2 {
  28. public static ArrayList singleElement(ArrayList al) {
  29. ArrayList newAL = new ArrayList();
  30. Iterator it = al.iterator();
  31. while(it.hasNext()) {
  32. Object obj = it.next();
  33. if(!newAL.contains(obj)) {
  34. newAL.add(obj);
  35. }
  36. }
  37. return newAL;
  38. }
  39. public static void main(String[] args) {
  40. ArrayList al = new ArrayList();
  41. al.add(new Person("Lisi01",30));
  42. al.add(new Person("Lisi02",32));
  43. al.add(new Person("Lisi02",32));
  44. al.add(new Person("Lisi03",33));
  45. al.add(new Person("Lisi04",33));
  46. al.add(new Person("Lisi04",33));
  47. System.out.println(al);
  48. al = singleElement(al);
  49. System.out.println(al);
  50. }
  51. }
复制代码
[Person@811c88, Person@785d65, Person@3bc257, Person@153f67e, Person@15bdc50, Person@1dd3812]
[Person@811c88, Person@785d65, Person@153f67e, Person@15bdc50]

回复 使用道具 举报 1 0
本帖最后由 王磊 于 2013-7-29 18:50 编辑
dicegame 发表于 2013-7-29 17:49
谢谢啊,原来contails封装了底层的equals,
我试着查了下源代码ArrayList.java(JDK1.7),可找不到,
源代 ...

在jdk文件夹中有一个src.jar包,这里面存放的就都是Java封装好的功能的所有源码。
也可以在MyEclipse中ctrl+shift+T,然后查找你要看的源码。
回复 使用道具 举报
王磊 发表于 2013-7-29 18:49
在jdk文件夹中有一个src.jar包,这里面存放的就都是Java封装好的功能的所有源码。
也可以在MyEclipse中ctr ...

谢谢,刚才没仔细搜,找到了:lol
回复 使用道具 举报
该问题已解决,烦请版主分一下类啦{:soso_e113:}
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马