Java.uitl包中的 ArrayList 和HashSet類 我們都用過,但是我們可能都沒有去,深入研究過其內部的結構 。都是實現了Collection的類 ,Collection是一個標准
ArrayList
其實就相當與一個動態數組,我們每增加一個元素,他啊都會將元素增加到ArrayList中並且為這個元素分配指定索引 就像一個數組一樣 。這個索引就是從0開始 1 2 34 。。。。
HashSet
看到Hash我們就知道,它的內部結構了,學過數據結構我們都知道hash表是如何插入元素 和 搜索元素,利用hash表我們可以快速的查找元素,而不用像數組一樣進行遍歷 。
在HashSet中 我們插入元素的時候 ,他會首先判斷HashSet中否有和這個元素相等的元素,如果有 那麼就不插入 。所以說HashSet中沒有重復元素。
HashSet可以實現元素的快速查找,這是利用hashCode來實現的 。
HashCode是怎樣獲得的呢? 在java中 如果我們不覆蓋父類的 hashCode方法 那麼hashCode是根據對象的內存地址計算而來。 當然我們也可以重載hashCode方法 。
在哈希表中,比如說有1-31 的索引 ,我們不是按照常規插入一個元素 索引增加一個,而是根據對象的hashCode來計算這個對象應該在表的哪個位置 .然後就把這個元素插入到這個索引對應的區域。對應的查找的時候也是這樣,是根據 對象的hashCode直接 查找指定索引對應的元素,這樣大大提高了速度 。
如果我們自己重寫了 hashCode() 我們不應該修改產生hashCode的字段,否則的話可能導致內存的洩漏、
看下面幾個程序的結果: 有一個類
class MyTest
{
int x;
int y;
public MyTest(int x,int y)
{
this.x=x ;
this.y=y ;
}
}
1、
package me.test;
import java.util.*;
public class ReflectTest2
{
public static void main(String[]args)
{
//面向父類的編程或者面向接口編程
Collection c1=new ArrayList() ; //ArrayList類是一個數組 實現了Collection接口
MyTest t1=new MyTest(2,2) ;
MyTest t2=new MyTest(3,4) ;
MyTest t3=new MyTest(2,2) ;
c1.add(t1) ;
c1.add(t2) ;
c1.add(t3) ;
c1.add(t1) ;
System.out.println(c1.size());
}
}
2、
package me.test;
import java.util.*;
public class ReflectTest2
{
public static void main(String[]args)
{
//面向父類的編程或者面向接口編程
Collection c1=new HashSet() ;
MyTest t1=new MyTest(2,2) ;
MyTest t2=new MyTest(3,4) ;
MyTest t3=new MyTest(2,2) ;
c1.add(t1) ;
c1.add(t2) ;
c1.add(t3) ;
c1.add(t1) ;
System.out.println(c1.size());
}
}
3、
package me.test;
import java.util.*;
public class ReflectTest2
{
public static void main(String[]args)
{
//面向父類的編程或者面向接口編程
Collection c1=new HashSet() ;
MyTest t1=new MyTest(2,2) ;
MyTest t2=new MyTest(3,4) ;
MyTest t3=new MyTest(2,2) ;
c1.add(t1) ;
c1.add(t2) ;
c1.add(t3) ;
c1.add(t1) ;
System.out.println(c1.size());
}
}
class MyTest
{
int x;
int y;
public MyTest(int x,int y)
{
this.x=x ;
this.y=y ;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
MyTest other = (MyTest) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
}
4、
package me.test;
import java.util.*;
public class ReflectTest2
{
public static void main(String[]args)
{
//面向父類的編程或者面向接口編程
Collection c1=new HashSet() ;
MyTest t1=new MyTest(2,2) ;
MyTest t2=new MyTest(3,4) ;
MyTest t3=new MyTest(2,2) ;
c1.add(t1) ;
c1.add(t2) ;
c1.add(t3) ;
c1.add(t1) ;
t1.y=0;
c1.remove(t1);
System.out.println(c1.size());
}
}
class MyTest
{
int x;
int y;
public MyTest(int x,int y)
{
this.x=x ;
this.y=y ;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
MyTest other = (MyTest) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
}