java 比较几种常见循环方式的优劣
do-while 和 while 循环非常相似,区别在于表达式的值是在每次循环结束时检查而不是开始时。和正规的 while 循环主要的区别是 do-while 的循环语句保证会执行一次(表达式的真值在每次循环结束后检查),然而在正规的 while 循环中就不一定了(表达式真值在循环开始时检查,如果一开始就为 FALSE 则整个循环立即终止)。
do-while 循环只有一种语法:
<?php
$i = 0;
do {
echo $i;
} while ($i > 0);
?>
以上循环将正好运行一次,因为经过第一次循环后,当检查表达式的真值时,其值为 FALSE($i 不大于 0)而导致循环终止。
资深的 C 语言用户可能熟悉另一种不同的 do-while 循环用法,把语句放在 do-while(0) 之中,在循环内部用 break 语句来结束执行循环。以下代码片段示范了此方法:
<?php
do {
if ($i < 5) {
echo "i is not big enough";
break;
}
$i *= $factor;
if ($i < $minimum_limit) {
break;
}
echo "i is ok";
/* process i */
} while(0);
?>
如果还不能立刻理解也不用担心。即使不用此“特性”也照样可以写出强大的代码来。
add a note User Contributed Notes
do-while
rlynch at lynchmarks dot com
09-May-2006 05:02
I would not be as pessimistic about the potential uses of the do-while construction, myself. It is just about the only elegant way of coding blocks that must have at least a single pass of execution, and where various assessments can short-circuit the logic, falling through.
Consider the example of prompting a user to input a value for a variable. The code in while() format might be:
<?php
$result = null ;
while( $result === null )
{
print "Gimme some skin, bro!> ";
$result = trim( fgets( $stdin ) );
if( $result === '' )
$result = null ;
}
?>
Well, that works. Lets try it in do-while format:
<?php
$result = '';
do {
print "Gimme some skin, bro!> ";
$result = trim( fgets( $stdin ) );
}
while( $result === '' );
?>
See how it just "reads better"? You say to yourself, "set up $result, print a message, get a response, and continue do to that while the nincompoop fails to enter anything."
Likewise, that "Advanced C" programming example turns out to be the elegant "no goto" way to run through exceptionally involved pieces of block-logic, with a trivial 'break' able to get one all the way past all the unnecessary code in one fell swoop.
For just about every other 'while()' block application, it shouldn't be used. While() is what we expect, and while() is what we should use ... except when the surprisingly common "but we have to do it at least once" criterion pops up its pretty head.
rlynch AT lynchmarks DOT com
while(条件){循环体}
先判断条件,满足就执行循环体,不满足则退出;
do{循环体}while(条件)
先执行一次循环体,再判断条件,如果条件满足,继续执行,不满足,退出循环,最少执行一次;
for(; ; ){循环体}
首先会初始化变量,然后判断条件,满足条件执行循环体,然后执行增量,一般是i++、i--等,再次判断条件,满足继续执行循环体,再判断条件。初始化只有进入循环的第一次执行 。
集合一共有三种遍历方法,以list循环举例:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
list.add(i);
}
//for循环遍历
for (int i = 0, size = list.size(); i < size; i++) {
System.out.println(list.get(i));
}
//iterator迭代器遍历
Iterator<Integer> it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
//foreach循环
for (Integer i : list) {
System.out.println(i);
}
}
}
数据元素是怎样在内存中存放的?
主要有2种存储方式:
1、顺序存储,Random Access(Direct Access):
这种方式,相邻的数据元素存放于相邻的内存地址中,整块内存地址是连续的。可以根据元素的位置直接计算出内存地址,直接进行读取。读取一个特定位置元素的平均时间复杂度为O(1)。正常来说,只有基于数组实现的集合,才有这种特性。Java中以ArrayList为代表。
2、链式存储,Sequential Access:
这种方式,每一个数据元素,在内存中都不要求处于相邻的位置,每个数据元素包含它下一个元素的内存地址。不可以根据元素的位置直接计算出内存地址,只能按顺序读取元素。读取一个特定位置元素的平均时间复杂度为O(n)。主要以链表为代表。Java中以LinkedList为代表。
每个遍历方法的实现原理是什么?
1、传统的for循环遍历,基于计数器的:
遍历者自己在集合外部维护一个计数器,然后依次读取每一个位置的元素,当读取到最后一个元素后,停止。主要就是需要按元素的位置来读取元素。
2、迭代器遍历,Iterator:
每一个具体实现的数据集合,一般都需要提供相应的Iterator。相比于传统for循环,Iterator取缔了显式的遍历计数器。所以基于顺序存储集合的Iterator可以直接按位置访问数据。而基于链式存储集合的Iterator,正常的实现,都是需要保存当前遍历的位置。然后根据当前位置来向前或者向后移动指针。
3、foreach循环遍历:
根据反编译的字节码可以发现,foreach内部也是采用了Iterator的方式实现,只不过Java编译器帮我们生成了这些代码。
各遍历方式的适用于什么场合?
1、传统的for循环遍历,基于计数器的:
顺序存储:读取性能比较高。适用于遍历顺序存储集合。
链式存储:时间复杂度太大,不适用于遍历链式存储的集合。
2、迭代器遍历,Iterator:
顺序存储:如果不是太在意时间,推荐选择此方式,毕竟代码更加简洁,也防止了Off-By-One的问题。
链式存储:意义就重大了,平均时间复杂度降为O(n),还是挺诱人的,所以推荐此种遍历方式。
3、foreach循环遍历:
foreach只是让代码更加简洁了,但是他有一些缺点,就是遍历过程中不能操作数据集合(删除等),所以有些场合不使用。而且它本身就是基于Iterator实现的,但是由于类型转换的问题,所以会比直接使用Iterator慢一点,但是还好,时间复杂度都是一样的。所以怎么选择,参考上面两种方式,做一个折中的选择。
主父贡克霉: Java中经常会用到迭代列表数据的情况,本文针对几种常用的写法进行效率比较.虽然网上已经有了类似的文章,但是对他们的结论并不认同.常见的实现方法:1.for循环:for(int i = 0; i 2.foreach:for(Object obj : list) 这是一种简洁的写法,只能对...
清苑县13010864979: java语言中,比较while、do…while和for三种循环的异同. - ?
主父贡克霉: for循环的参数可以有3个,第一个参数先执行,然后按照第二个参数执行循环体,结束后执行第三个参数.do...while和while的区别是,do...while在执行循环体之前会执行do后面的语句,而while直接按照参数条件执行循环体.
清苑县13010864979: java的几种循环有啥区别 - ?
主父贡克霉: 和正规的 while 循环主要的区别是 do-while 的循环语句保证会执行一次(表达式的真值在每次循环结束后检查),然而在正规的 while 循环中就不一定了(表达式真值在循环开始时检查,如果一开始就为 FALSE 则整个循环立即终止). do-while...
清苑县13010864979: java中while, do…while, for, 'foreach'几种循环的特点? - ?
主父贡克霉: while()循环参数一定要是整形的:int,short,long类型,其他不行;do...while()循环 :是先执行do后面的代码,再进入while循环;for循环: 直接设定 i=? i《=? i++;的基本值自己都已经设定好了,在自己清楚基本值的情况下使用;foreach循环: 通常是遍历数组和集合的时候使用,第一个参数是你想获得值的类型,第二个参数是一个标记,自己取的,第三个参数是集合或者数组.
清苑县13010864979: java中for循环的几种写法 - ?
主父贡克霉: 以下为for循环的几种写法: /*** 方法一:最普通的不加思考的写法 * <p>*优点:较常见,易于理解 * <p>* 缺点:每次都要计算list.size()*/ for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); } /*** 方法二:数组长度提取出来 * <p>* 优点:...
清苑县13010864979: Java的循环有几种,都有什么作用 - ?
主父贡克霉: do{循环体}while(条件) 先执行循环体,再判断条件,如果条件满足,继续执行,不满足,退出循环,最少执行一次 while(条件){循环体} 先判断条件,满足就执行循环体,不满足退出 for(;;)这个不太好说,我举个例子你就明白了 从1循环到10,然后把1-10打印出来 for(int i=1;i<=10;i++){System.out.println(i); }
清苑县13010864979: java的这三种for循环有什么区别? - ?
主父贡克霉: 第一种是最普通的for循环 这个应该没啥好说的 第二种是第一种for循环的变种也可以说是简写 只能对数组或者是List这样的集合使用 这个是java 1.5新加入的 第三种不是for循环.使用的是迭代器 iterator 像是List这样的集合 一般多是用这种方法
清苑县13010864979: java中的流程控制语句中的三种循环控制语句 - ?
主父贡克霉: 三种分别是for循环、while循环、do…while循环.for循环,举例for(int i=0;i<5;i++){ };从0开始循环,每次加1,一直到4结束. while循环,举例while(true){};也就是当条件为真的时候执行,否则一次也不执行 do…while循环,举例 do {i =0;System.err.println(i)}while(i>1){};此情况下即使不满足条件也会执行do中的语句,这个适合while的区别.备注:具体用那种循环根据实际需要选择即可.
清苑县13010864979: java在循环中如何进行比较 - ?
主父贡克霉: 不知道我理解的对不对.你想的是每个月份最后有条数据,放的是这个月的总和.那遍历的时候你把每一项数据取出来,然后相加.根据月份判断就可以.每个月份开始初始化这个数据,把数据置0.结束把你组成总和的数据塞到list里面不就可以了么
清苑县13010864979: java中对集合对象list的几种循环访问总结 - ?
主父贡克霉: List一共有三种遍历方法,如下: import java.util.ArrayList; import java.util.Iterator; import java.util.List;public class Main {public static void main(String[] args) {List<Integer> list = new ArrayList<>();for (int i = 0; i < 10; i++) {list.add(i);} //for循环...