1.Map加强版;(增加检索的效率)
List 是有序可重复;
我们使用Map的时候一般这样写: Map a =new HashMap();//一般都是这样写 接口加一个实现类
Map接口的一个实现类 HashMap 他还有一个实现类就是HashTable 前者是线程安全的(就和StringBuilder,StringBuffer;ArrayList,Vector)他们类似
set 无序不可重复 新对象不能equals老的对象;
package TestMap;
import java.util.LinkedList;
/**
* 根据Map来实现自己的Map 上一个Map效率太低 这次我们改进
* @author Wang
* 说明 : Map的底层实现是根据 数组加链表实现的 下面我们来模仿一下
*/
public class MyMap002 {
LinkedList[] array = new LinkedList[9999]; //建立一个链表数组; 在链表的里面存放键值对
int size;
public void put(Object key,Object value) {
Map01 e = new Map01(key,value); //Map01中的存放键值对的类
int hash = key.hashCode();//这个方法的作用是 根据key这个对象的地址来生成一个hashcode码 每个对象的地址不同会生成不同码
hash = hash<0?-hash:hash;//这个地方有一个问题就是hashCode可能是一个负数 用这一句来避免 判断他是不是负数是负数的话就取相反数,不是的话 就不用改变;
int a = hash % array.length;//这样保证hash的值e都在 数组的索引范围内
if(array[a] == null) {//说明数组的这个位置还没存放链表 他将会是第一个
LinkedList list = new LinkedList();//建立一个新的链表对象准备放到数组里面
array[a] = list;
list.add(e);//将键值对放到list里面
size++;
}else {//在这里要考虑Map的键相同的时候 value要被覆盖 所以要遍历里面的list的key是否和传入的key相同
LinkedList list = array[a];//去除array[a]里面现有的链表 进行遍历
for(int i=0; i<list.size();i++) {
Map01 e2 = (Map01)list.get(i);//取出来都是Object类型的了 要强制转换
if(e2.key.equals(key)){
e2.value =value;//键相同就直接覆盖
return ;//要是覆盖以后就跳出这个put方法
}
}
array[a].add(e);//直接在array【a】这个链表后面加了一个e
size++;
}
}
public Object get(Object key) {//通过key来查找 就先通过key的地址来确定是哪一个数组 然后遍历链表里面的key就行了
int hash = key.hashCode();
int a = hash % array.length;
LinkedList list = array[a];
for(int i=0;i<list.size();i++) {
Map01 e =(Map01)list.get(i);
if(e.key == key) {
return e.value;
}
}
return null;
}
public int size() {
return size;
}
public static void main(String[] args) {
MyMap002 map1 = new MyMap002();
map1.put("wang", 1);
map1.put("wang1", 2);
map1.put("wang2", 3);
map1.put("wang3", 4);
map1.put("wang", "哈士奇");
System.out.println(map1.get("wang"));
System.out.println(map1.size());
}
}
2.set(一个继承Collection接口)
他是无序不可重复(List是有序可重复);
我们用的最多的就是HashSet(他的底层实现是通过Map)(set里面的元素其实就是Map里面的key);
package TestSet;
import java.util.HashSet;
import java.util.Set;
/**
* Set的基本方法 Hash的底层实现用的是Map 他的元素就是Map的Key所以不可重复
* @author Wang
*
*/
public class testSet01 {
public static void main(String[] args) {
Set set = new HashSet();
set.add("aaaa");
set.add("bbbb");
set.add(new String("aaaa"));//重复了 会覆盖
System.out.println(set.size());
set.remove("aaaa");
}
}
3.MySet
package TestSet;
import java.util.HashMap;
/**
* 自己写一个简单的Set
* @author Wang
*
*/
public class MySet {
HashMap map;
private static final Object PRESENT = new Object();//这个用于map的Value(无意义) HashSet的元素是Map的keys
public MySet() {
map = new HashMap();
}
public int size() {
return map.size();
}
public void add(Object o) {
map.put(o,PRESENT);//Set的不可重复性就利用了这个
}
public static void main(String[] args) {
MySet a = new MySet();
a.add("aaa");
a.add("aaa");//重复的会自动覆盖
a.add("ccc");
System.out.println(a.size());
}
}
注意:
hashCode():两个内容相同的对象一定有相同的hashCodes,但是相同的hashcodes相同不一定对象相等;(可以这样说如果两个对象的equals为true 那么他们的hashcode()一定相等,反之则不然);
hashCode()是可以重写[hashcode()和equals一般同时重写 可以使用source生成;
容器的三大接口 : list,set,map用的都很多;