Map接口,是和Collection接口并列的一个接口,它其实是一个有着映射关系的集合"key-value(也可以叫entry)"(就像数学中的函数一样),由于key存储时用的是set来存储,所以key是不可重复的,而value是用Collection存储的,它是可重复的,整个的key-value是用set来存放的,即一个key有唯一一个对应的value(就像y = k(x)一样),所以它也是不可重复的。
Map接口中具体有以下几个实现类:
HashMap(Map接口的主要实现类,允许key与value的值都为null)
2、LinkedHashMap
3、TreeMap
4、Hashtable
一、下面具体来说说Map的主要实现类HashMap:
其实HashMap中的的很多方法都和Collection很是类似,具体的方法如下:
put(Object key, Object value); //向当前集合中添加一个key-value对,若当前集合已存在相同的key值时则覆盖
②Object get(Object key); //根据对应的key值返回其对应的value值
③boolean containsKey(Object key); //判断对应key值的key-value是否存在于当前集合中
④boolean containsValue(Object value); //判断对应value值的key-value是否存在与当前集合中
⑤int size(); //返回当前集合中的元素个数
⑥void clear(); //清空当前集合
⑦Object remove(Object key); //移除对应key值的key-value对,并返回value的值;
⑧boolean isEmpty(); //判断当前集合是否为空
⑨void putAll(Map m); //将一个Map集合m中的所有entry对全部填入当前集合中去
equals(Map e); //判断两个Map集合是否完全相同
下面说一个注意事项:
import
java.util.HashMap;
import
java.util.Map;
import
org.junit.Test;
public
class
TestHashMap {
@Test
public
void
HashMapTest1(){
Map
A
=
new
HashMap ();
A
.put(
"A"
, 123);
A
.put(
"C"
, 321);
A
.put(
"R"
, 345);
A
.put(
"F"
, 123);
A
.put(
new
Woman(
"美女"
,18), 456);
A
.put(
new
Woman(
"美女"
,18), 654);
System.
out
.println(
A
);
}
class
Woman{
private
String
name
;
private
int
age
;
public
Woman() {
super
();
}
public
Woman(String
name
,
int
age
) {
super
();
this
.
name
=
name
;
this
.
age
=
age
;
}
@Override
public
int
hashCode() {
final
int
prime
= 31;
int
result
= 1;
result
=
prime
*
result
+
age
;
result
=
prime
*
result
+ ((
name
==
null
) ? 0 :
name
.hashCode());
return
result
;
}
@Override
public
boolean
equals(Object
obj
) {
if
(
this
==
obj
)
return
true
;
if
(
obj
==
null
)
return
false
;
if
(getClass() !=
obj
.getClass())
return
false
;
Woman
other
= (Woman)
obj
;
if
(
age
!=
other
.
age
)
return
false
;
if
(
name
==
null
) {
if
(
other
.
name
!=
null
)
return
false
;
}
else
if
(!
name
.equals(
other
.
name
))
return
false
;
return
true
;
}
@Override
public
String toString() {
return
"Woman [name="
+
name
+
", age="
+
age
+
"]"
;
}
}
}//
{A=123, R=345, C=321, F=123, Woman [name=美女, age=18]=654}
在上面的例子我们可以看到,在我存入集合A中的时候有几个key值重复和value重复的对象,在我们向HashMap中添加一个元素时,会先调用存入对象所属类的equals方法去判断当前集合中是否有key值与该元素相同,若存在,则后来的元素会覆盖前面的元素,因此被当做key值存入对象所属类必须重写equals()方法和HashCode()方法(具体重写方法请参考我的其他文章),而values只需要重写equals(Object e)方法;而当存入key值不同,但value相同的entry时,HashMap是允许我们这样做的
下面我们来谈谈Map的遍历方法
虽然Map接口是和Collection并行的一个接口,但是它的遍历方法与Collection接口截然不同,因为在Map中存的都是一个个的entry,也就是说它是成对存在的,所以遍历时就不会显得像Collection那么容易了,具体的遍历方法有以下几个:
①Set keySet() 用于遍历key值,与values()的遍历结果一一对应
②Collection values() 用于遍历value值
③Set entrySet() 用于遍历每一个entry
具体遍历实现如下:
①遍历key集(承接上一个例子)
Set
set
=
A
.keySet();
//遍历key集
for
(Object
each
:
set
){
System.
out
.println(
each
);
}
②遍历value
Collection
col
=
A
.values();
//遍历value集
for
(Object
each
:
col
)
{
System.
out
.println(
each
);
}
③遍历key-value集
//方法一 利用Map的get(Object key)方法
for
(Object
each
:
set
)
{
System.
out
.println(
each
+
"--->"
+
A
.get(
each
));
}
//方法二 利用entrySet()方法遍历
Set
set1
=
A
.entrySet();
for
(Object
each
:
set1
)
{
Map.Entry
obj
= (Map.Entry)
each
;
System.
out
.println(
obj
);
}
二、关于LinkedHashmap
其实LinkedHashmap与HashMap的不同之处就在于LinkedHashMap使用了链表进行添加和插入的维护,也就是说在遍历的时候是按照添加顺序遍历的,但在存储的时候依旧按照Set存储一样是无序的
三、关于TreeMap
TreeMap与TreeSet类似,他有以下特点:
①存入TreeMap的Key必须是同一类型的
②可以按照key的属性进行自然排序和定制排序,和TreeSet一样,TreeMap要求存入的key值所在的自定义类要么实现Comparable接口中的colpareTo(Object e)方法并重写(自然排序),要么自定义类中实现Comparator接口中的compare(Object e1,Object e2)并重写,