在 Java 中迭代列表是非常基本的操作,但多年来它经历了一些重大变化。我们将在给定的示例中介绍所有这些更改。为简单起见,我创建了一个简单的 String
列表,如下所示:
List<String> list = Arrays.asList(new String[]{"One","Two","Three","Four","Five"});
现在让我们学习迭代它。
这从一开始就在语言中,但我不再喜欢这种类型的循环。它容易出错且令人困惑——主要是在使用 greater-than
或 less-than
运算符时。
//Using standard for loop for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); }
迭代器是比标准 for 循环更好的方法。它使用集合框架自己的 Iterator 接口。
//Using Iterator Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); }
这是一个 for 循环,但它隐藏了处理索引的复杂性,因此使用起来很漂亮。
//Using enhanced for loop for (String str : list) { System.out.println(str); }
在底层,这种形式的迭代使用 Iterator
接口并调用其 hasNext
和 next
方法。
阅读更多:Java 中增强的 for (for-each) 循环< /a>
Tell-Don't-Ask 是一个著名的设计原则,它提倡将数据与操作该数据的函数(基本OOP 概念)。在以上所有示例中,我们要求执行特定的迭代,而不是将迭代的细节留给底层库并专注于任务。
Java 8 函数式编程解决了这个问题还有一个问题——forEach
方法接受类型为 消费者
。顾名思义,Consumer
的实例将通过其 accept
方法使用提供给它的内容。
//Using forEach() with Consumer interface list.forEach(new Consumer<String>() { @Override public void accept(String name) { System.out.println(name); } });
这里,forEach
方法将为 list
中的每个元素调用给定 Consumer
的 accept
方法,并且依次打印出名称。你可以在 accept 方法中做任何你想做的事。
上面的 forEach
方法非常有效并且在设计方面是正确的,但是它太冗长了。您可以使用 lambda 表达式将其修剪为更精简的版本。
//Using forEach() - lambda expression list.forEach((final String name) -> System.out.println(name));
lambda 表达式的标准语法要求将参数括在括号中,并提供类型信息并以逗号分隔。 Java 编译器也提供了一些宽容并且可以推断类型。省去类型很方便,需要更少的努力,而且噪音更小。这里的类型信息是从集合本身推断出来的,因此您也可以保留该信息。
//Using forEach() - without type information list.forEach(name -> System.out.println(name));
现在太好了。使用这种迭代有助于我们专注于应用程序逻辑——而不是编写对列表进行迭代的非生产性代码。
快乐学习!!
地址:https://www.cundage.com/article/iterate-list-examples.html