简单集合实现三(HashMap和HashSet)

来源:互联网 发布:unity3d pool 编辑:程序博客网 时间:2024/06/07 05:55

  上两篇文章我们实现了自己的ArrayListLinkedList,也清楚了ArrayList查找方便,修改困难。LinkedList修改方便,查找困难。我们也经常遇到问HashMapHashSet的异同,其实HashSet的实现就是使用了HashMap只不过它只用到了HashMap中的key值。所以学会了HashMap也就明白了HashSet

  首先我们知道HashMap中是存放键值对的,也就是会有一个key值一个Value值。Key值不能重复,判断标准是equals比较。这也就导致了HashSet中存放的都是无序而不可重复的值,这也是它和ArrayList的区别,ArrayList中存放的是有序可重复的数值。那HashSet的存取速度与ArrayList比较怎么样呢?实际情况是介于ArrayLisLinkedList之间,因为它的实现是数组+链表的形式。

  这我们就要看HashMapkey值得实现,前面说了它是数组+链表实现的,同时根据他的命名也能知道他使用了Hash值。Hash值的引入也是为了更方便查找,相当于字典中的索引一样,每一个对象对应了一个Hash值(不同对象可以有相同的hash值),以该对象hash值根据一定规则处理后的数字作为数组下标存放该值,那么当需要取出该值时,不需要遍历数组中所有的对象,只需要根据该对象的hash值所代表的索引直接定位到该对象即可,大大加快了查询速度。下面以一个图来说明这个问题(图中数据仅举例说明并非真实)


  下面描述一下是如何数组+链表存入数据,包含keyvalue


下面我们就用代码来实现简单的HashMapHashSet

public class MyMap {  int size;  List[] arr = new LinkedList[1999];  public void put(Object key, Object value){    Entry e = new Entry(key,value);    int a = key.hashCode()%arr.length;    if(arr[a] == null){    List list = new LinkedList();    arr[a]=list;    list.add(e);  }else{    LinkedList list = (LinkedList) arr[a];    for(int i = 0; i < list.size(); i++){    Entry e2 = (Entry) list.get(i);      if(e2.key.equals(key)){        e2.value = value;        return;      }    }    arr[a].add(e);    }  }  public Object get(Object key){    int a = key.hashCode()%arr.length;    if(arr[a] != null){    LinkedList list = (LinkedList) arr[a];    for(int i = 0; i < list.size(); i++){      Entry e = (Entry) list.get(i);        if(e.key.equals(key)){          return e.value;        }      }    }    return null;  }} class Entry{  public Entry(Object key, Object value) {    this.key = key;    this.value = value;  }  Object key;  Object value;}


 

 

只需要把HashMap中的key值单独拿出来实现了HashSet

public class MyHashSet {  HashMap map;  private static final Object PRESENT = new Object();  public MyHashSet(){    map = new HashMap();  }  public int size(){    return map.size();  }  public void add(Object o){    map.put(o, PRESENT);  }}