java for循环死循环_Java for循环进化

java for循环死循环

Iteration is one of the most basic requirement in any programming language & of all, “for” is the most widely used loop in java for iteration. We will see the evolution of java for loop iteration techniques.

迭代是所有编程语言中最基本的要求之一,而“ for”是Java中迭代次数最广泛使用的循环。 我们将看到Java for循环迭代技术的发展。

Java for循环进化 (Java for loop Evolution)

We will work on an example for displaying names of actors from a Collection. For the sake of simplicity let’s take a List and set this up:

我们将通过一个示例来显示Collection中演员的姓名。 为了简单起见,让我们列出一个列表并进行设置:

List<String> actors = Arrays.asList("Jack Nicholson", "Marlon Brando", "Robert De Niro", "Al Pacino", "Tom Hanks");

Let’s start looking at the for loop evolution over different java releases.

让我们开始研究不同Java版本上的for循环演变。

基本的循环 (Basic for loop)

Main elements of, “for” loop are initialization, termination condition, and loop increment logic. Let’s see a sample here:

“ for”循环的主要元素是初始化,终止条件和循环增量逻辑。 让我们在这里看到一个示例:

for (int i = 0; i < actors.size(); i++) {
  System.out.println(actors.get(i));
}

If we want to iterate over a collection which is not of type List, we will not have a get(int index) method which will give us the indexed value from the collection. Hence in Java 1.2 Iterators were introduced. Let’s see how we solve the same problem with Iterators:

如果我们要遍历不是List类型的集合,则将没有get(int index)方法,该方法将为我们提供该集合的索引值。 因此在Java 1.2中引入了迭代器 。 让我们看看我们如何使用迭代器解决相同的问题:

for (Iterator<String> iterator = actors.iterator(); iterator.hasNext();) {
 System.out.println(iterator.next());
}

for-each(增强了循环) (for-each (Enhanced for loop))

This loop was introduced in Java 5, it removes the clutter, ceremony and the opportunity for error by hiding the iterator or index variable completely. Let’s see this in action:

此循环是Java 5中引入的,它通过完全隐藏迭代器或索引变量来消除混乱,仪式和出错的机会。 让我们来看看实际情况:

for (String actor : actors) {
 System.out.println(actor);
}

The above examples are of types of External Iterators, here control & termination logic resides with an external iterator. This can result in overall complexity and may be error-prone.

以上示例是外部迭代器的类型,此处的控制和终止逻辑驻留在外部迭代器中。 这会导致整体复杂性,并且容易出错。

内部forEach循环 (Internal forEach loop)

In Java 8, with the introduction of Functional Interface & Lambda’s, Java architects have provided us with an Internal Iterator (forEach loop) supported by Collection framework and can be used with the collections object. This method performs a given action for each element of the collection. Let’s see this in more detail:

Java 8中 ,随着功能接口Lambda的引入,Java架构师为我们提供了Collection框架支持的内部迭代器(forEach循环),并且可以与collections对象一起使用。 此方法对集合的每个元素执行给定的操作。 让我们更详细地看一下:

Method Signature: public void forEach(Consumer action)

方法签名public void forEach(Consumer action)

forEach takes an implementation of Consumer (Functional Interface), which has an accept(T t) method to execute the logic inside the loop. Let’s see the implementation:

forEach采用了Consumer (功能接口)的实现,该实现具有accept(T t)方法来执行循环内的逻辑。 让我们看一下实现:

actors.forEach(new Consumer<String>() {
	public void accept(String actor) {
		System.out.println(actor);
	}
});

Here forEach method is given an Anonymous Inner Class of Consumer interface. This class has an accept(T t) method which is being invoked for all the values of the collection. This code suffers from a design flaw where a new class is created each time we use forEach by passing the anonymous inner class.

这里为forEach方法提供了一个消费者内部匿名类 接口 。 此类具有accept(T t)方法,该方法将为集合的所有值调用。 此代码存在设计缺陷,每次使用forEach时,都会通过传递匿名内部类来创建一个新类。

ForLoopEvolution$1.class
ForLoopEvolution.class

This solution looks more verbose and complex than the earlier loops. Let’s try and refactor this in a simplified manner. The entire functional interface implementation can be written as a Lambda function, which is more intuitive. Let’s see this in action:

与以前的循环相比,此解决方案看起来更加冗长和复杂。 让我们尝试以简化的方式重构它。 整个功能接口的实现可以编写为更直观的Lambda函数。 让我们来看看实际情况:

actors.forEach((e) -> {
 System.out.println(e);
 });

For each element e, the actor is being displayed in the console. This code can be simplified further by removing unnecessary curly braces and brackets.

对于每个元素e,参与者都显示在控制台中。 可以通过删除不必要的花括号和方括号来进一步简化此代码。

actors.forEach(e -> System.out.println(e));

The main advantage of using lambda instead of the anonymous inner class is that there’s no bytecode pollution, no class creation, instead, the call to the lambda is deferred until runtime. Let’s see the bytecode for more details:

java invokedynamic

使用lambda代替匿名内部类的主要优点是没有字节码污染,没有类创建,而是将lambda的调用推迟到运行时。 让我们看一下字节码以获取更多详细信息:

invoke dynamic helps the JVM to create the bytecode from lambda expression and delay the execution until runtime.

动态调用可以帮助JVM从lambda表达式创建字节码,并将执行延迟到运行时。

方法推论 (Method Inference)

Method Inference further removes some more ceremony & verbosity. Let’s refactor to pass method inference instead of lambda:

方法推论进一步消除了更多的仪式和冗长。 让我们重构以传递方法推断而不是lambda:

actors.forEach(System.out::println);

One additional advantage of using the internal iterator is, the code is almost ready for parallelism. In Java 8 with the introduction of the stream api, we can run the code in parallel without the need of synchronization. A parallel stream can be created from the collection to process our functionality.

使用内部迭代器的另一个好处是,代码几乎可以并行处理了。 在Java 8中,通过引入流api ,我们可以并行运行代码,而无需同步。 可以从集合中创建并行流以处理我们的功能。

actors.parallelStream().forEach(System.out::println);

摘要 (Summary)

Internal Iterators are less complex & less error-prone, better maintainable. Code with an internal iterator usage can easily be made parallel.

内部迭代器不那么复杂,也不容易出错,可维护性更好。 具有内部迭代器用法的代码可以很容易地并行化。

Code Link: GitHub URL for Java Code

代码链接Java代码的GitHub URL

翻译自: https://www.journaldev.com/18118/java-for-loop-evolution

java for循环死循环

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值