温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

For循环和While循环的区别是什么

发布时间:2021-06-15 11:04:40 来源:亿速云 阅读:255 作者:Leah 栏目:web开发

For循环和While循环的区别是什么,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

最简单的情况是对列表中的每个元素执行操作。

List<Integer> list = List.of(1, 2, 3); // bare for loop.  for(int i : list) {    System.out.println("int = "+ i); }// controlled for each list.forEach(i -> System.out.println("int = " + i));

在这种最简单的情况下,无论哪种方法都没有太大优势。但第二种方法可以不使用bare for循环,而且语法更简洁。

我觉得forEach语句也有问题,应该只应用于副作用安全的方法。我所说的安全副作用是指不改变程序状态。上例只是记录日志,因此使用无碍。其他有关安全副作用的示例是写入文件、数据库或消息队列。

不安全的副作用会更改程序状态。下面为示例及其解决方法:

// bad side-effect, the loop alters sum int sum = 0; for(int i : list) {     sum += i; } System.out.println("sum = " + sum);// no side-effect, sum iscalculated by loop sum = list        .stream()        .mapToInt(i -> i)        .sum(); System.out.println("sum = " + sum);

另一个常见的例子:

// bad side-effect, the loop alters list2 List<Integer> list2 = new ArrayList<>(); for(int i : list) {    list2.add(i); } list2.forEach(i -> System.out.println("int = " + i));// no sideeffect, the second list is built by the loop list2 = list          .stream()          .collect(Collectors.toList()); list2.forEach(i -> System.out.println("int = " + i));

当你需要处理列表项方法中的索引时就会出现问题,但可以解决,如下:

// bare for loop with index: for(int i = 0; i < list.size(); i++) {     System.out.println("item atindex "        + i        + " = "        + list.get(i)); }// controlled loop with index: IntStream.range(0, list.size())    .forEach(i ->System.out.println("item at index "     + i     + " = "     + list.get(i)));

老生常谈的问题:读取文件中的每一行直到文件读取完毕如何解决?

BufferedReader reader = new BufferedReader(        new InputStreamReader(       LoopElimination.class.getResourceAsStream("/testfile.txt"))); // while loop with clumsy looking syntax String line; while((line = reader.readLine()) != null) {    System.out.println(line); }reader = new BufferedReader(        new InputStreamReader(       LoopElimination.class.getResourceAsStream("/testfile.txt"))); // less clumsy syntax reader.lines()    .forEach(l ->System.out.println(l));

应对上述情况有一个非常简便的lines方法,可以返回Stream类型。但是如果一个字符一个字符地读取呢?InputStream类没有返回Stream的方法。我们必须创建自己的Stream:

InputStream is =    LoopElimination.class.getResourceAsStream("/testfile.txt"); // while loop with clumsy looking syntax int c; while((c = is.read()) != -1) {   System.out.print((char)c); } // But this is even uglier InputStream nis =    LoopElimination.class.getResourceAsStream("/testfile.txt"); // Exception handling makes functional programming ugly Stream.generate(() -> {    try {       return nis.read();    } catch (IOException ex) {       throw new RuntimeException("Errorreading from file", ex);    } })  .takeWhile(ch -> ch != -1)  .forEach(ch ->System.out.print((char)(int)ch));

这种情况下while循环看起来更好。此外,Stream版本还使用了可以返回无限项目流的  generate函数,因此必须进一步检查以确保生成过程终止,这是由于takeWhile方法的存在。

InputStream类存在问题,因为缺少peek  方法来创建可轻松转换为Stream的Iterator。它还会抛出一个检查过的异常,这样函数式编程就会杂乱无章。在这种情况下可以使用while语句让PR通过。

为了使上述问题更简洁,可以创建一个新的IterableInputStream类型,如下:

static class InputStreamIterable implements Iterable<Character> {   private final InputStream is;   public InputStreamIterable(InputStreamis) {     this.is = is;   }   public Iterator<Character>iterator() {      return newIterator<Character>() {                       public boolean hasNext() {            try {              // poor man's peek:              is.mark(1);              boolean ret = is.read() !=-1;              is.reset();              return ret;            } catch (IOException ex) {              throw new RuntimeException(                     "Error readinginput stream", ex);            }         }         public Character next() {            try {              return (char)is.read();            } catch (IOException ex) {              throw new RuntimeException(                    "Error readinginput stream", ex);            }         }      };   } }

这样就大大简化了循环问题:

// use a predefined inputstream iterator: InputStreamIterable it = new InputStreamIterable(     LoopElimination.class.getResourceAsStream("/testfile.txt")); StreamSupport.stream(it.spliterator(), false)    .forEach(ch -> System.out.print(ch));

如果你经常遇到此类while循环,那么你可以创建并使用一个专门的Iterable类。但如果只用一次,就不必大费周章,这只是新旧Java不兼容的一个例子。

关于For循环和While循环的区别是什么问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注亿速云行业资讯频道了解更多相关知识。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI