黑马程序员技术交流社区

标题: ArratLis将自定义对象person作为元素存到ArrayList集合中 [打印本页]

作者: 樊其杰    时间: 2013-4-13 22:28
标题: ArratLis将自定义对象person作为元素存到ArrayList集合中
本帖最后由 樊其杰 于 2013-4-15 10:56 编辑
  1. class person{
  2. private String name;
  3. private int age;
  4. public int getAge() {
  5. return age;
  6. }
  7. public void setAge(int age) {
  8. this.age = age;
  9. }
  10. public String getName() {
  11. return name;
  12. }

  13. person(String name,int age){
  14. this.name=name;
  15. this.age=age;
  16. }
  17. //复写equals方法
  18. public boolean equals(Object obj){
  19. if(!(obj instanceof person))
  20. return false;
  21. person p=(person)obj;
  22. return this.name.equals(p.name)&&this.age==p.age;
  23. }
  24. }

  25. public class ArrayListTest2 {

  26. public static void main(String[] args) {
  27. ArrayList<person> al=new ArrayList<person>();
  28. al.add(new person("lisi01", 20));
  29. al.add(new person("lisi02", 24));
  30. al.add(new person("lisi03", 24));
  31. al.add(new person("lisi04", 24));
  32. al.add(new person("lisi01", 20));
  33. //调用singleElement方法
  34. singleElement(al);

  35. Iterator<person> it=al.iterator();
  36. while(it.hasNext()){
  37. Object obj=it.next();
  38. person p=(person)obj;
  39. System.out.println(p.getName()+"::"+p.getAge());
  40. }
  41. }
  42. //去除集合中重复的元素
  43. public static ArrayList<Object> singleElement(ArrayList<person> al){
  44. ArrayList<Object> newal=new ArrayList<Object>();

  45. Iterator<person> it=al.iterator();
  46. while(it.hasNext()){
  47. Object obj=it.next();
  48. if(!newal.contains(obj)){
  49. newal.add(obj);
  50. }
  51. }
  52. return newal;
  53. }

  54. }
复制代码
上面代码中person类复写equals方法看视频后还是不太懂,听的迷迷糊糊,哪位大神能不能具体讲讲?

作者: ①人←①城市    时间: 2013-4-13 22:42
本帖最后由 ①人←①城市 于 2013-4-13 22:52 编辑

如果直接调用equals是调用Object中的:

public boolean equals(Object obj)指示其他某个对象是否与此对象“相等”。
这个对象的相比,一般是直接将对象进行比较.
而两个new 实例的equals是不相等的.

所以很多时候要自己重写此方法来定制自己所需要的.


作者: 刘策    时间: 2013-4-13 22:47
list集合判断元素唯一性就是依据对象的equals方法,public boolean equals(Object obj){
if(!(obj instanceof person))这是在判断 这个obj接收来的对象是否属于Personal这个类。如果不是就返回,这里最好抛异常,
return false;
person p=(person)obj;向下转型。强制将父类的引用转成子类类型,
return this.name.equals(p.name)&&this.age==p.age;此个判断person类中的姓名是否相等,因为它们都是字符串,所以它们可以调用字符串中的equals方法。这个年龄是int型的,用比较运算符比较,如果姓名和年龄都相等的话,就返回true,说明这两个人是同一个人,只要有一个不同就返回false,说明不是一个人,&&这个运算符当左边为false时,右边不运算。
}
作者: 李易烜    时间: 2013-4-13 22:49
当我们重写了对象的equals方法,一般情况下(这里我指这些对象不需要放到Set或Map中仅仅是比较需要,或者虽然放到Set或Map中,但是get和set时用的是同一对象)是没有问题的,但是,有些情况下就不同了;举个例子
public class Person(){

private int id;

private String name;

//define getter and setter here, omited



public void equals(Object obj){

if (!(obj instanceof Person))
            return false;
return super.equals(obj) && ((Member) obj).getId() == this.getId();

}

}
上述class中没有覆盖hashCode方法,因此这个时候用的是Object.hashCode()的返回值;我们来测试一下
public class TestHashCode extends TestCase {
        public void testMap() {
        Person p1 = new Person(1,"aaa"),p2 = new Person(1,"bbb");
        Map map = new HashMap();
        map.put(p1,p1);
        Member value = (Person)map.get(p2);
        System.out.println(value.getName());
    }
}
请注意,这两个对象是相等的,可以从equals()的定义看出来;运行TestHashCode ,结果是NullPointerException;

现在添加hashCode()到Person中
public int hashCode() {
        
        return this.getId() * 37 ;
    }
重运行TestHashCode ;huh,我们想要的结果出现了,“aaa”

为什么添加person.hashCode()前,得不到person对象;因为java中默认的hashCode是根据对象的地址计算得到的,虽然p1.equals(p2)=true,但是p1,p1有不同的内存地址,所以有不同的hashCode;所以通过p2是不能得到value的,这个时候value==null;添加hashCode()后,两个对象有相同hashCode,所以能得到

java中Set是通过Map实现的,所以Map和Set的所有实现类都要注意这一点

HashMap是通过链地址法解决hash collision的,并且新对象都是添加到表头的(这个看了好久才明白,数据结构都还老师了)




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2