集合遍历的四种方式?
创建一个List集合:
public static void main(String[] args) { List<String> listNames = new ArrayList<>(); listNames.add("qiuqiu"); listNames.add("kaka"); listNames.add("beibei"); listNames.add("hutu"); listNames.add("wangzai"); }
这个list包含我们小区的所有小狗的名字。注意在语句的右边<>的使用
ArrayList<>();
这个语法从Java7开始使用,允许我们以一种更严谨的方式声明泛型的集合,因为编译器可以从左边推测出右边的参数类型(因此叫做“类型引用”)
经典for循环
这种迭代方法在编程中非常熟悉,其中计数器变量从集合中的第一个元素运行到最后一个元素
for (int i = 0; i < listNames.size(); i++) { String name = listNames.get(i); System.out.println(name); }
pros:
- 这是编程中最熟悉的构造
- 如果我们需要访问并使用计数器变量,比如打印小狗狗们的的数字顺序:1,2,3……
cons:
- 使用计数器变量要求集合必须以基于索引的形式(如ArrayList)存储元素,并且我们必须提前知道集合的大小
迭代的方式
由于经典循环方式的限制,创建了使用迭代器的方式,这种方式允许我们迭代各种集合。
因此你可以看到Collection接口定义了每个集合必须实现iterator()方法,需要先创建迭代器对象。
在List上用迭代器遍历:
Iterator<String> itr = listNames.iterator(); while (itr.hasNext()) { String name = itr.next(); System.out.println(name); }
在Set上用迭代器遍历:
Set<String> set = new HashSet<>(); set.add("a"); set.add("b"); set.add("c"); set.add("d"); Iterator<String> itr = set.iterator(); while (itr.hasNext()) { String letter = itr.next(); System.out.println(letter); }
在Map上用迭代器遍历(迭代keySet()):
Map<String, Integer> grade = new HashMap<>(); grade.put("Operating System", 90); grade.put("Computer Network", 92); grade.put("Software Engineering", 90); grade.put("Oracle", 90); Iterator<String> itr = grade.keySet().iterator(); while (itr.hasNext()) { String key = itr.next(); Integer value = grade.get(key); System.out.println(key + "=>" + value); }
加强for循环
从Java 5开始,程序员可以使用一种更简洁的语法来遍历集合-加强for循环。
for (String s : listNames) { System.out.println(s); }
注意:加强for循环实际上在背后使用的是迭代器。这意味着编译时Java编译器会将增强型for循环语法转换为迭代器构造。 新的语法为程序员提供了一种更方便的迭代集合的方式。
使用Lambda表达式的forEach
Java 8引入了Lambda表达式,介绍了一种遍历集合的全新方式-forEach方法
listNames.forEach(name -> System.out.println(name));
forEach方法与之前的方法最大的区别是什么?
在之前的方法中(经典for循环,迭代器和加强for循环),程序员可以控制集合是如何迭代的。迭代代码不是集合本身的一部分,它是由程序员编写的,因此称为外部迭代。
相比之下,新方法将迭代代码封装在集合本身中,因此程序员不必为迭代集合编写代码。 相反,程序员会在每次迭代中指定要做什么 - 这是最大的区别!
因此术语forEach内部迭代:集合处理迭代本身,而程序员传递动作 - 即每次迭代需要做的事情。