2020-08-28 HashMap的遍历

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(包含键的set集合)】
         *              ② 使用迭代器遍历集合,
         *              ③ 使用迭代器的iter.hasNext()方法判断下一个元素是否为空,使用iter.next()方法取出键;
         *              ④ 根据键就可以得到value;
         *
         *           方法二:
         *              ① 将(key--value)键值对存放到节点
         *              ② 将节点保存到set集合中
         *              ③ 将节点存放到迭代器中
         *              ④ 既然在迭代器中,就可以使用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()方法,通过键获取值。

  一句话,没有条件使用迭代器,创造条件也要使用迭代器。

你可能感兴趣的:(Java基础,java,java)