jdk1.5和jdk1.6以下程序执行结果不一样?今天看了张孝祥的反射的视频,有类似下面的一段程序。 public static void main(String[] args) {
Collection colls = new ArrayList();
RefletTest pt1 = new RefletTest(3, 3);
RefletTest pt3 = new RefletTest(3, 3);
colls.add(pt1);
colls.add(pt3);
colls.add(pt1);
System.out.println(colls.size());
colls = new HashSet();
colls.add(pt1);
colls.add(pt3);
colls.add(pt1);
pt1.x = 14;
colls.remove(pt1);
System.out.println(colls.size());//张孝祥视频中colls的size是2
//我自己在1.6环境下删除后colls的size是1
}

解决方案 »

  1.   

    System.out.println(colls.size());//张孝祥视频中colls的size是2
    //我自己在1.6环境下删除后colls的size是1要么是1要么是0,不可能是2.
      

  2.   

    我当然是有把握才回答的。
    还有为什么我会说要么是1要么是0,那是我不了解你的RefletTest具体什么情况,有没有重写hashCode,equals等。要不你把RefletTest的代码贴全,把你的运行结果也贴上来,然后再找问题。
      

  3.   


    public class RefletTest { int x;
    int y; RefletTest() {
    } RefletTest(int x, int y) {
    this.x = x;
    this.y = y;
    } public String str1 = "abc";
    public String str2 = "babba";
    public String str3 = "buck"; @Override
    public String toString() {
    return str1 + "," + str2 + "," + str3;
    } public String contact(String a, String b) {
    return a + b;
    }}
      

  4.   


    // pt1.x = 14;
    // colls.remove(pt1);
    运行结果:
    3
    2 pt1.x = 14;
    colls.remove(pt1);
    运行结果:
    3
    1
      

  5.   

    我的也是JDK1.6的,运行结果也是 1,  注释 colls.remove(pt1); 结果是2 这里只是考察 HashSet 和ArrayList的区别!
      

  6.   

    1.ArrayList 是以数组为基础实现的一个List,所以ArrayList允许有重复的元素。        Collection colls = new ArrayList();
            RefletTest pt1 = new RefletTest(3, 3);
            RefletTest pt3 = new RefletTest(3, 3);
            colls.add(pt1);
            colls.add(pt3);
            colls.add(pt1);这段代码执行完后colls中会有3个元素,分别是两个pt1,一个pt3.所以:
     System.out.println(colls.size()); 的结果就是 3。2.HashSet是以HashMap为基础实现的一个Set,先在简单看看HashMap的原理。
     总的来说HashMap用一个数组作为容器(桶)。这个数组的初始长度length假设为16.数组中保存的是Entry对象,Entry包含了Key,Value还有一个类型是Entry的属性next,指向下一个Entry。Entry是一个单向链表。
     
    当你put(Key, Value)的时候:
     a.先得到Key的hashCode值hash.
     b.用这个hash值通过一个算法求的在数组中的位置index。
     【这个算法在Hashtable中是(hash & 0x7FFFFFFF) % tab.length,在HashMap中是 hash & (length - 1),
     这样会确保index是小于数组长度length的。】
     c.用<Key,Value>新建一个Entry.把这个Entry对象放在数组中。
       当两个Key计算得到的index一样了怎么办,此时它会先看两个key的hash值是不是一样,一样的话在用equals比较两个对象是不是同一个。
       如果hash值一样,并且equals为true说明是同一个Key,那么就用这Value覆盖旧的Value,
       如果hash值不一样,或者hash值一样但是equals为false,那么新建一个Entry。并把next指向数组中原来index位置的Entry。   HashSet就相当于HashMap的KeySet。        colls = new HashSet();
            colls.add(pt1);
            colls.add(pt3);
            colls.add(pt1);colls = new HashSet();重新初始化为一个HashSet;
    第一句colls.add(pt1);之前colls是空的。这句执行完加了一个元素。
    第二句colls.add(pt3);
     虽然pt1 = new RefletTest(3, 3);pt3 = new RefletTest(3, 3);但是你的RefletTest并没有重写hashCode,
     是从Object继承的,默认实现是返回一个整数。你可以把这个整数是根据对象的内存地址得到的。
     既然是通过new得到的两个对象,那么他们的内存地址肯定不一样。所以hashCode也不一样。
     所以这句会再加一个元素到colls中。现在colls有2个元素了。
    第三句colls.add(pt1);pt1已经添加到colls中了,pt1.hashCode() == pt1.hashCode(),pt1.equals(pt1),
     所以不会重复添加。现在colls还是2个元素。
     
    3. 数组,集合(Set,List,Map,Queue)保存的只是对象的引用,并不是对象本身,或者对象的复制品。
     所以:pt1.x = 14; 这句执行完colls中的和colls外的pt1的x都会改变。而且由于你没有重写hashCode和equals这句并不会对集合操作起到影响。(即便是重写了也不会有影响(只持有引用))。
    4.remove操作,找Key的过程(比较hashCode是不是一样,一样再根据equals比较)
     colls.remove(pt1);会把colls中的pt1移除。此时colls只剩下pt3一个元素了。
    所以 System.out.println(colls.size());的结果为1.
      

  7.   

    楼主看看HashSet的add方法就明白了
      

  8.   

    是否重复..Set  不重复
    List 可重复