`
m635674608
  • 浏览: 5028539 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

java forEach实现原理

    博客分类:
  • java
 
阅读更多
java.util.List实现了java.lang.Iterable接口.

jdk api文档中是这样描述Iterable接口的:实现这个接口允许对象成为 "foreach" 语句的目标。不过咋一看Iterable接口并没啥特别之处,只是定义了一个迭代器而已。
[java] view plaincopy

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


究竟是如何实现foreach的呢,想想可能是编译器做了优化,就看了下最终编译成的字节码
[java] view plaincopy

    public class Iterable_eros {  
          
        List<String> strings;  
      
        public void display(){  
            for(String s : strings){  
                System.out.println(s);  
            }  
        }  
          
    }  

相应的字节码为
[java] view plaincopy

    public void display (){  
    line0    : aload_0    
               getfield  java.util.List my.lang.Iterable_eros.strings  
               invokeinterface  java.util.Iterator java.util.List.iterator() 1  
               astore_2    
               goto  line30  
    line13   : aload_2    
               invokeinterface  java.lang.Object java.util.Iterator.next() 1  
               checkcast  java.lang.String  
               astore_1    
    line23   : getstatic  java.io.PrintStream java.lang.System.out  
               aload_1    
    line27   : invokevirtual  void java.io.PrintStream.println(java.lang.String)  
    line30   : aload_2    
               invokeinterface  boolean java.util.Iterator.hasNext() 1  
               ifne  line13  
    line39   : return    

果然没猜错哈!可以看到,foreach语法最终被编译器转为了对Iterator.next()的调用。而作为使用者的我们, jdk并没用向我们暴露这些细节,我们甚至不需要知道Iterator的存在,认识到jdk的强大之处了吧。

为了证实自己的想法,用Iterator写了个遍历List的方法查看了字节码,果然跟foreach的形式基本一样,当然这是后话~
[java] view plaincopy

    public void display(){  
            for(String s : strings){  
                System.out.println(s);  
            }  
              
            Iterator<String> iterator = strings.iterator();  
            while(iterator.hasNext()){  
                String s = iterator.next();  
                System.out.println(s);  
            }  
        }  

[java] view plaincopy

    public void display (){  
    line0    : aload_0    
               getfield  java.util.List my.lang.Iterable_eros.strings  
               invokeinterface  java.util.Iterator java.util.List.iterator() 1  
               astore_2    
               goto  line30  
    line13   : aload_2    
               invokeinterface  java.lang.Object java.util.Iterator.next() 1  
               checkcast  java.lang.String  
               astore_1    
    line23   : getstatic  java.io.PrintStream java.lang.System.out  
               aload_1    
    line27   : invokevirtual  void java.io.PrintStream.println(java.lang.String)  
    line30   : aload_2    
               invokeinterface  boolean java.util.Iterator.hasNext() 1  
               ifne  line13  
               aload_0    
               getfield  java.util.List my.lang.Iterable_eros.strings  
               invokeinterface  java.util.Iterator java.util.List.iterator() 1  
               astore_1    
    line49   : goto  line69  
    line52   : aload_1    
               invokeinterface  java.lang.Object java.util.Iterator.next() 1  
               checkcast  java.lang.String  
               astore_2    
    line62   : getstatic  java.io.PrintStream java.lang.System.out  
               aload_2    
    line66   : invokevirtual  void java.io.PrintStream.println(java.lang.String)  
    line69   : aload_1    
               invokeinterface  boolean java.util.Iterator.hasNext() 1  
               ifne  line52  
    line78   : return    

 

   为什么遍历arraylist的时候 for循环会比迭代器快呢
因为 arraylist 底层是由数组组成的,在java中为了通用迭代器,所以性能上有一定的损失
对于底层由数组组成的arraylist 这种对象,如果使用for循环,直接由索引获取对象,速度是很快的,使用迭代器要向下一个一个的遍历,速度是稍微一点点的慢过for

但是迭代器发光的地方并不在底层由数组构成的集合上,迭代器用在 底层由双向指针链表构成的linkedlist 上,效率大大高于for循环。
如 果使用for循环遍历 底层由双向指针链表构成的linkedlist的话,他会每次都从头遍历一次,知道获取你给定的下标,然后开始下一次遍历,。越往后速度越慢。下标越大, 速度越慢。但是对于迭代器,他不是根据下标完成的遍历,每取得一个对象后,他会根据这个对象的尾部指针取得下一个对象的内存位置,直接从内存位置取出内 容,这一点是for循环所不及的。

分享到:
评论

相关推荐

    java中jsp实现购物车原理

    本教程将介绍如何利用Java的Servlet和JSP技术实现一个简单的购物车功能。 首先,我们需要理解购物车的基本概念。购物车是一个存储用户选择商品的地方,用户可以在浏览商品时将其添加到购物车,然后在结账时进行结算...

    Java实现拖拽列表项的排序功能

    们需要在后端处理拖拽事件,...理解这些原理后,无论是JavaFX还是Swing,甚至是其他平台的UI框架,都能灵活地实现拖拽排序功能。通过这个功能,我们可以提高用户的交互体验,让他们能更直观、便捷地调整列表项的顺序。

    编译原理课程设计(Java语言)-LR分析法,foreach循环语句

    在编译原理课程设计中,Java语言被选为实现LR分析法的重要工具,这涉及到编译器构造的核心技术。LR分析法是一种自底向上的语法分析方法,它用于解析源代码,将源代码的词法单元流转化为抽象语法树(AST)。LR分析器...

    Java中的迭代器和foreach原理

    Java中的迭代器(Iterator)和foreach循环是两种常用的遍历集合和数组的方式。迭代器模式是一种行为设计模式,它的核心作用在于允许用户遍历任何集合或聚合对象的元素,而无需暴露其底层结构。在Java中,迭代器主要...

    25个经典Spark算子的JAVA实现

    根据给定文件的信息,本文将详细介绍25个经典Spark算子的Java实现,并结合详细的注释及JUnit测试结果,帮助读者更好地理解Spark算子的工作原理及其应用方式。 ### Spark算子简介 在Apache Spark框架中,算子是用于...

    Java for each实现机制代码原理解析

    Java for each实现机制代码原理解析 Java for each实现机制代码原理解析是Java语言中的一种遍历集合元素的机制,通过使用for each循环可以简洁地遍历集合中的元素。下面我们将深入探讨Java for each实现机制的代码...

    13.foreach循环_java_

    在Java编程语言中,`foreach`循环,也称为增强型for循环或迭代器循环,是处理数组和集合数据的一种简洁高效的方式。这个小视频详细介绍了如何在Java中正确使用`foreach`循环,让我们深入探讨一下相关知识点。 首先...

    java+js实现下拉框提示搜索功能

    Java 和 JavaScript 结合实现下拉框提示搜索功能是前端开发中的常见需求,它极大地提升了用户交互体验,使得用户能够快速找到所需的信息。这种功能广泛应用于各种网页表单、搜索引擎、推荐系统等。以下是对这个主题...

    分页功能实现java

    首先,分页功能的实现原理是在每次用户请求显示数据时,仅加载当前页需要的数据,而不是一次性将所有数据加载到客户端。这样可以大幅降低数据传输的量,加快页面的响应速度,并且减少服务器内存的占用。实现分页功能...

    用JAVA程序实现数据库的增删改

    本教程将重点讲解如何使用Java程序实现数据库的增删改(CRUD)操作,并结合JSP和Servlet技术进行Web交互。Oracle作为广泛使用的数据库管理系统,是我们实现这些功能的理想选择。 首先,我们需要了解Java中的JDBC...

    Java遍历集合方法分析(实现原理、算法性能、适用场合)_.docx

    Java中的集合遍历是编程实践中常见的操作,不同的遍历方式有着不同的实现原理、性能特点以及适用场景。本文将深入分析Java中三种主要的遍历集合方法:传统的for循环遍历、迭代器遍历以及foreach循环遍历。 1. **...

    foreach循环

    本篇文章将深入探讨`foreach`循环的工作原理、用法以及其在不同编程语言中的应用。 `foreach`循环,也称为“对于每个”循环,主要用于遍历数组或集合中的每一个元素。它简化了迭代过程,无需手动管理索引或计数器。...

    java-array-list-foreach

    Java中的ArrayList是集合框架的重要组成部分,它是一种动态数组,允许我们在需要时添加或删除元素。...理解`foreach`循环的工作原理以及ArrayList的特性,可以帮助我们更好地利用这些工具来编写高效、易读的Java代码。

    Java遍历集合方法分析(实现原理、算法性能、适用场合)

    每种方式都有其特定的实现原理、性能特点以及适用场景。 1. 传统的for循环遍历: 这是最基础的遍历方式,通过一个计数器变量从0开始逐个访问集合中的元素,直到达到集合的大小。实现原理是直接通过索引访问集合中...

    Java和Android的Lru缓存及其实现原理

    Java提供了LinkedHashMap,可以用该类很方便的实现LRU算法,Java的LRULinkedHashMap是直接继承了LinkedHashMap,进行了极少的改动后可以实现LRU算法。  二、Java的LRU算法  Java的LRU算法的基础是LinkedHashMap...

    Android代码-java-bible

    Java8 Foreach Hexo搭建博客 分分钟部署一个Hexo环境 各种配置详解 开始写作吧 开发者指南 git - 简明指南 Jersey-2.x用户指南 REST 实战 Java Servlet 3.1 规范 MyBatis中文指南 Apache Shiro 用户指南 Spring...

    DIY函数式方法原理

    在本主题“DIY函数式方法原理”中,我们将探讨如何在Java中实现四个关键的函数式编程方法:forEach、map、flatMap和filter。 1. **forEach**:这个方法来源于Java 8中的Stream API,用于遍历集合中的每一个元素。它...

    java8 官方文档.

    Java 8官方文档详细解释了这些特性的使用和原理,同时还包含了API参考、教程、示例代码等内容,是Java开发者必备的学习资料。通过深入学习和实践,开发者能够更好地利用Java 8的特性来提高开发效率和软件质量。

    java8源码包含sun

    然而,了解这个包可以帮助我们深入理解Java的内部工作原理。 1. **模块化系统(Module System)** 在Java 8中,引入了Jigsaw项目,实现了模块化系统,目的是提高系统的可维护性和安全性。虽然"sun"包不在模块系统...

    2020 java经典面试题总汇.zip

    - Collection与Iterable接口,以及foreach循环的工作原理 - 泛型的使用,类型擦除的概念,以及通配符的应用 4. **多线程** - 创建线程的三种方式:继承Thread类、实现Runnable接口、使用ExecutorService - 线程...

Global site tag (gtag.js) - Google Analytics