IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> java迭代map的四种方式以及迭代器原理 -> 正文阅读

[Python知识库]java迭代map的四种方式以及迭代器原理

迭代器原理:
什么是迭代器,使用迭代器的好处?

迭代器就是用来遍历集合中对象的东西,也就是说,对于集合,我们不像对原始数组那样通过直接访问元素来迭代的,而是通过迭代器来遍历对象。这么做的好处是将对于集合类型的遍历行为与被遍历集合对象分离,这样以来,就不需要关心该集合类型的具体实现是怎么样的。只要获取这个集合对象的迭代器便可以遍历这个集合中的对象。而像遍历对象顺序以及怎么访问对象元素这些细节,全部由它自己的迭代器来处理。

迭代器怎么实现的?

首先集合要先实现iterable接口来表示此对象是可以进行迭代的。而实现iterable接口的对象实现了iterator方法,这个方法返回了一个Iterator对象。一个迭代器对象需要Iterator接口中的方法:hasNext(),next(),remove()。remove()方法会删除最近一次调用的元素,如果remove()之前没有调用next()的话直接调用remove()会产生报错信息(IllegalStateException)。我们在进行对集合对象迭代的时候,next()会返回当前对象第一个对象并返回,然后next会指向下一个元素,hasNext方法就是看这个指针后面还有没有元素了。

迭代器的陷阱?

使用for迭代的时候不可以使用集合进行remove操作。这时候需要使用迭代器进行迭代,然后使用迭代器中的remove方法进行删除。

为什么会产生这样的错误?

remove()方法在删除元素的时候,还会修改一个修改次数的标志位modCount,如果iterator的expectedModCount与modCount的大小不相等时,会抛出一个ConcurrentModificationException异常。modCount的目的主要是为了防止当前对象迭代过程中存在其他线程对当前对象的修改。

// iterable接口源代码

public interface Iterable<T> {
    /**
     * Returns an iterator over elements of type {@code T}.
     *
     * @return an Iterator.
     */
    Iterator<T> iterator();

    default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }
    default Spliterator<T> spliterator() {
        return Spliterators.spliteratorUnknownSize(iterator(), 0);
    }
}

// iterator接口源代码

public interface Iterator<E> {
    /**
    * 如果迭代拥有更多元素,那么返回true
    */
    boolean hasNext();
    /**
    * 返回iteration中的下一个元素
    */
    E next();
    /**
    * 如果删除一个集合中的元素没有调用这个方法,二十直接中集合中删除,那么这个迭代器的行为没有被指定
    */
    default void remove() {
        throw new UnsupportedOperationException("remove");
    }
    /**
    * 遍历集合中的剩余元素(如果之前调用了两次next()那么只会遍历集合中剩余元素
    * 使用案例:
    * Iterator<Integer> it = map.keySet().iterator();
        it.next();
        it.next();
        it.forEachRemaining(System.out::println);
    */
    default void forEachRemaining(Consumer<? super E> action) {
        Objects.requireNonNull(action);
        while (hasNext())
            action.accept(next());
    }
}

HashMap中实现迭代的核心代码:

        final Node<K,V> nextNode() {
            Node<K,V>[] t;
            Node<K,V> e = next; // 对象属性中的next是下一个值
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
            if (e == null)
                throw new NoSuchElementException();
            // next = e.next 如果e.next为null,那么继续找数组下一个不为null的值
            if ((next = (current = e).next) == null && (t = table) != null) {
                do {} while (index < t.length && (next = t[index++]) == null);
            }
            return e;
        }
        public final void remove() {
            Node<K,V> p = current;
            if (p == null)
                throw new IllegalStateException();
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
            current = null;
            K key = p.key;
            removeNode(hash(key), key, null, false, false);
            expectedModCount = modCount;

遍历map的四种方式

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.HashMap;

public class MapTest {
    public static void main(String[] args) {
        HashMap<Integer,Integer> map = new HashMap();
        map.put(0,1);
        map.put(2,2);
        map.put(1,2);
        map.put(4,5);
        map.put(3,4);
        // 遍历hashmap entry foreach
        Set<Map.Entry<Integer,Integer>> ent = map.entrySet();
        for(Map.Entry<Integer,Integer> entry:ent){
            System.out.println(entry.getKey()+"  :  "+entry.getValue());
            //map.remove(0);
        }
        System.out.println();
        // 通过keySet或者values()遍历
        Set<Integer> set = map.keySet();
        for(Integer key:set){
            System.out.println(key+"  --  "+map.get(key));
        }
        Collection<Integer> set1 = map.values();
        for(Integer val:set1){
            System.out.println(val);
        }
        System.out.println();
        // iterator原理是什么 通过iterator遍历map
        Iterator<Map.Entry<Integer,Integer>> iter = map.entrySet().iterator();
        while(iter.hasNext()){
            Map.Entry entry = iter.next();
            System.out.println(entry.getKey()+"  :  "+entry.getValue());
            iter.remove();
        }
        System.out.println();
        Iterator<Integer> keys = map.keySet().iterator();
        while(keys.hasNext()){
            int k = keys.next();
            System.out.println(k+" -- "+ map.get(k));
        }

    }
}

参考链接:https://blog.csdn.net/fuzhongmin05/article/details/72460658

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2021-09-03 11:50:39  更:2021-09-03 11:51:36 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 12:44:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码