Map_put_get.java
/**
* java.util.Map
* Map在实际开发中是一种非常常用的数据结构。
* 存储元素看起来像是一个"多行两列的表格"。
* Map中每个元素有两部分组成,分别为key,value
* 俗称:键值对
* 而从Map中查询数据的原则是根据key查找对应的value。
* 所以Map要求key不允许重复(Map中不允许有key的equals
* 比较为true.)
*
* Map是一个接口,规定了Map这种数据结构操作的相关方法。
* 常用实现类:java.util.HashMap(俗称:散列表,哈希表)
*
* @author soft01
*
*/
public class pm01_Map_put_get {
public static void main(String[] args) {
Map<String,Integer> map = new HashMap<String,Integer>();
/*
* V put (K k,V v)
* 将给定的key-value对存入Map中。
* 由于Map中不允许出现重复的key,所以
* 若使用Map中已经存在的key存入一个新
* 的value时,是做替换value操作,那么put
* 方法的返回值就为该key原来对应的value,
* 即:返回被替换的value
* 若指定的key在Map中不存在,则存入后返回
* 值为NULL.
*/
Integer num = map.put("语文", 99);
System.out.println(num);
map.put("数学", 89);
map.put("英语", 97);
map.put("物理", 98);
map.put("化学", 95);
System.out.println(map);
//重复的key则是替换value操作
num = map.put("语文", 77);
System.out.println(num);
System.out.println(map);
/*
* V get(K k)
* 根据给定的key获取对应的value,若
* 给定的key在Map中不存在,则返回值为null
*/
num = map.get("数学");
System.out.println("数学:"+num);
/*
* V remove(K k)
* 将给定的key所对应的键值对从当前Map中
* 删除,返回值为该key所对应的value值。
*/
num = map.remove("语文");
System.out.println(map);
System.out.println("old:"+num);
System.out.println("size:"+map.size());
boolean tf = map.containsKey("体育");
System.out.println("key是否包含:"+tf);
tf = map.containsValue(97);
System.out.println("value是否包含:"+tf);
}
}
Map_iterate.java
/**
* Map的遍历
* 遍历Map有三种方式:
* 1:遍历所有的key
* 2:遍历所有的键值对(Entry)
* 3:遍历所有的value(用的比较少)
* @author soft01
*
*/
public class am01_Map_iterate {
public static void main(String[] args) {
// Map<String,Integer> map = new HashMap<String,Integer>();
/*
* LinkedHashMap是可以按照put元素时的顺序
* 遍历Map中的所有元素
*/
Map<String,Integer> map = new LinkedHashMap<String,Integer>();
map.put("语文", 99);
map.put("数学", 89);
map.put("英语", 97);
map.put("物理", 98);
map.put("化学", 95);
System.out.println(map);
/*
* HashMap本身不是线程安全的
* 若希望将现有的Map转换为线程安全的,
* 可以使用Collections的静态方法将其
* 转换。
*/
map = Collections.synchronizedMap(map);
/*
* 遍历所有的key
* Set<K> keySet()
* 将当前Map中所有的key存入一个Set集合后
* 返回。
*/
Set<String> keySet = map.keySet();
keySet.forEach((k)->System.out.println(k));
/*
* 遍历所有的键值对
* Map中每一组键值对由内部类Entry的实例表示
* Entry有两个常用方法:
* getKey,getValue.这两个方法用于获取当前
* Entry实例表示的这组键值对中的key与value
*
* set<Entry> entrySet()
* 将当前Map中每组键值对存入一个Set集合后返回
*/
Set<Entry<String,Integer>> entrySet = map.entrySet();
for(Entry<String,Integer> e : entrySet) {
String key = e.getKey();
Integer value = e.getValue();
System.out.println(key+":"+value);
}
/*
* 将当前Map中所有的Value存入一个集合后
* 返回。
*/
Collection<Integer> values = map.values();
for(Integer value : values) {
System.out.println(value);
}
}
}
Key
/**
* HashMap内部由数组实现,是当今查询速度最快的
* 数据结构。
* HashMap根据key元素决定这组键值对应当存放在
* 数组的位置,并且也是根据key元素得到位置来检索
* 数组中键值对以此省去了遍历数组的过程。
*
* 但是使用HashMap时应当尽量避免出现链表的情况。
* HashMap中链表产生的原因:
* HashMap是根据key元素的hashcode方法返回的数字
* 经过散列计算得到该键值对应当存放在数组的哪个
* 位置,而根据key元素equals比较查看当前key是否
* 已经存在于map中,若存在则直接替换该位置这个key
* 所对应的value,但是若数组该位置已经存在键值对,
* 并且key与当前准备存放的键值对中的Key的equals
* 比较不同时,则会在数组当前位置产生链表。这样在
* 将来根据key检索时会出现遍历链表的时候就会在
* HashMap中产生链表,影响查询性能。
*
* 总结:当key元素hashcode值相同,但是equals比较不同
* 时就会在HashMap中产生链表,影响查询性能。
*
* JDK中提供的类作为key元素没问题,都已妥善处理完毕。
* 当我们自己定义的类需要作为key元素时,也要妥善的
* 重写上述的两个方法。
*
* 在API手册的Object类中对equals,hascode方法的
* 重写有相关说明。重写准则:
1:成对重写,即:当我们需要重写一个类的equals方法
时,就应当连同重写hashcode方法。
2:一致性,即:当两个对象equals比较为true时,hascode
返回的数字应当相等。反之亦然,因为若两个对象equals
比较返回不同但是hashcode相等时在HashMap中会产生链表。
3:hashcode的稳定性,即:当参与equals比比较的属性值没有
发生改变的前提下,多次调用hashcode方法返回的数字应当
相等,不应当变化。
* @author soft01
*
*/
public class am02_Key {
private int x;
private int 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;
am02_Key other = (am02_Key) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
}
October 17, 2017 9:26 PM
2017.10.17