HashMap:
根据hashCode方法生成的hash值存储数据,大多数情况下可以直接定位到它的值,因而具有很快的访问速度,但遍历顺序却是不确定的。HashMap最多只允许一条记录的键为null,允许多条记录的值为null。HashMap非线程安全,即任一时刻可以有多个线程同时写HashMap,可能会导致数据的不一致。如果需要满足线程安全,可以用 Collections的synchronizedMap方法使HashMap具有线程安全的能力,或者使用ConcurrentHashMap。
1.HashMap遍历方法:
①keySet遍历
②entrySet遍历
③迭代器keySet遍历
④迭代器entrySet遍历
1.HashMap有哪些特点:
①JDK1.2版本,线程不安全,运行效率快。
②允许用null 作为key或是value。
③存储结构:哈希表。
④HashMap实现了Map接口,Map接口对键值(集合)对进行映射。⑤Map中不允许重复的键。
⑥Map接口有两个基本的实现,HashMap和TreeMap。
⑦TreeMap保存了对象的排列次序,而HashMap则不能。
3.怎么遍历??
如下代码和注释:
package hashMap;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class Demo01 {
public static void main(String[] args) {
HashMap<Integer, String> map = new HashMap<>();
//增
map.put(1, "广州");
map.put(2, "成都");
map.put(3, "北京");
map.put(4, "上海");
map.put(5, "南京");
map.put(6, "铁岭");
System.out.println(map);
//删除
map.remove(2);
System.out.println("删除后的集合"+map);
//改 先删除,在添加
map.remove(6);
map.put(6, "成都");
System.out.println("修改后的集合"+map);
//查询
System.out.println("根据键查询值:"+map.get(3));
System.out.println("keySet遍历");
for (Integer key:map.keySet()
) {
System.out.println(key+" "+map.get(key));
}
System.out.println("entrySet遍历");
for (Map.Entry<Integer,String> entry:map.entrySet()
) {
System.out.println(entry.getKey()+" "+entry.getValue());
}
/**
* 1.实现遍历 首先fori循环不能用,因为没有索引,不能和i增量相关联
*
* 2.不能使用(Iterator)迭代器,因为迭代器专属服务于Collection接口
*
* 3.不能使用拉姆达表达式,因为拉姆达表达式本质上也是使用迭代器
*
* 解决办法:
* 方法一:
* ① 使用keySet() 方法把map集合中的key存放到set集合中,keySet() 的返回值是【set<k>(包含键的set集合)】
* ② 使用迭代器遍历集合,
* ③ 使用迭代器的iter.hasNext()方法判断下一个元素是否为空,使用iter.next()方法取出键;
* ④ 根据键就可以得到value;
*
* 方法二:
* ① 将(key--value)键值对存放到节点
* ② 将节点<Entry></>保存到set集合中
* ③ 将节点存放到迭代器<Interator>中
* ④ 既然在迭代器中,就可以使用hasNext()方法判空和使用next()方法取出键值对(key--value)保存到新建的节点中
* ⑤ 将刚刚保存键值对(key--value)的节点中的key和value分别取出打印
*/
Set<Integer> set=map.keySet();
Iterator<Integer> iter=set.iterator();
while(iter.hasNext()){//迭代器的hasNext方法:如果next方法返回的是一个元素而不是一个异常,就返回true
Integer key= iter.next();
System.out.println("key:"+key+",value:"+map.get(key));
}
/**
* 如果在while循环的时候使用Iterator的iter.next()判空来作为循环条件,就会出现
* ①从第二个添加开始输出,然后隔一个再输出
* ②会报元素找不到异常(NoSuchElementException),
* 原因:
* ① iter.next()方法直接就取出的下一个元素,因此集合内就少一个元素,
* 再在while方法内调用的iter.next()方法时,就会继续取出下一个元素,因此会隔一个元素打印
* ② iter.hasNext()方法判断下一个元素是否为空,不会从集合中取出元素
*/
System.out.println();
Set<Map.Entry<Integer,String>> set1=map.entrySet();
Iterator<Map.Entry<Integer,String>> it= set1.iterator();
while(it.hasNext()){
Map.Entry<Integer,String> entey=it.next();
System.out.println("key:"+entey.getKey()+"value:"+entey.getValue());
}
}
}
两个方法的异同;
不同之处在于第一个方法只是将键的值存到set集合中,而第二种方法是将键值对存到集合中
再总结一下:
方法一:
将键值对(key–value)中的键(key)保存到Collection所属的集合中,这样就可以用Iterator(迭代器)使用hasNext()方法和next()方法,通过键获取值。
方法二:
让键值对成为一个节点(Entry),将节点(Entey)保存到Collection所属的集合中,这样就可以用Iterator(迭代器)使用hasNext()方法和next()方法,通过键获取值。
一句话,没有条件使用迭代器,创造条件也要使用迭代器。