四时宝库

程序员的知识宝库

Java 里各个容器的最全遍历方法汇总


遍历可以说是对数据结构最常见的操作。之前说基本的操作是“增删改查”,但是遍历,就是要让我们找到,要对谁进行“增删改查”。一般,会结合一些 if 判断,来进行操作。

所以在准备这期文章时,我在删除那里停顿了很久。想不明白为什么边遍历边删除,要用 Iterator + remove,后来自己写了一个例子,放在文末。自觉非不用也没有关系,就是写出来很奇怪。欢迎批评指正。

套路:

  • for/while 循环,最普通的那种挨个取,要求容器有序;
  • for 增强版:增强 for 循环;
  • Iterator for、while版,新建 Iterator 对象,然后具体再写成 for 或者 while 的循环,用 hasNext 来做是否进行下一次的判断,再新建临时对象,打印。

遍历 List

先初始化一个 ArrayList:

List<String> ids = new ArrayList<>();
ids.add("007");
ids.add("008");
ids.add("009");
复制代码
  • 遍历第一种,因为 list 有序,可以用索引来遍历:
// List 遍历1
System.out.println("ids 遍历 for1");
for (int i=0; i<ids.size(); i++) {
    System.out.println(ids.get(i));
}
复制代码
  • 第二种,用增强 for 循环,写法不一样,和索引就没有关系了:
// List 遍历2
System.out.println("ids 遍历 for2");
for (String temp: ids) {
    System.out.println(temp);
}
复制代码
  • 第三种,定义迭代器,然后写在 for 或者 while 里面:
// List 遍历 for版 Iterator
System.out.println("ids 遍历 Iterator1");
for (Iterator iterator = ids.listIterator(); iterator.hasNext();) {
    String temp = (String) iterator.next();
    System.out.println(temp);
}
// List 遍历 while版 Iterator
System.out.println("ids 遍历 Iterator2");
Iterator<String> iterator = ids.iterator();
while (iterator.hasNext()) {
    Object temp = iterator.next();
    System.out.println(temp);
}
复制代码

以上内容的运行结果如下:

遍历 Set

Set 就无序了,所以,没有索引来用。这里顺带复习一下 HashSet 和 TreeSet 的区别,分别对应两种遍历方法:

  • 第一种用增强 for 循环,用了 HashSet,更无序一点:
// 初始化一个 HashSet
Set<Integer> ages = new HashSet<>();
ages.add(8);
ages.add(88);
ages.add(36);
// Set 遍历 1
for (Integer i: ages) {
    System.out.println(i);
}
复制代码

运行结果:

  • 第二种,同样用 for,但是用 Iterator 来做:
Set<Integer> ages2 = new TreeSet<>();
ages2.add(8);
ages2.add(88);
ages2.add(36);
// Set 遍历 Iterator
for (Iterator iterator2 = ages2.iterator(); iterator2.hasNext();) {
    Integer temp = (Integer) iterator2.next();
    System.out.println(temp);
}
复制代码

运行结果就变成了:8 36 88(分行显示)。就已经按大小排好的顺序了。

遍历 Map

遍历 Map 的本质是在遍历 Set。

先初始化一个 课程表,用 HashMap 来存:

// 初始化一个 map
Map<String, String> courses = new HashMap<>();
courses.put("1001", "English");
courses.put("1003", "Novel Reading");
courses.put("1002", "History");
System.out.println("初始化的 Map:" + courses.toString());
复制代码
  • 第一种方法,取 KeySet,然后用这个 Key,挨个再 get 对应的value:
// 遍历 Map 法1:根据 key ,取 value
Set<String>  keySet = courses.keySet();
for (String  courseId: keySet) {
    System.out.println(courseId + ": " + courses.get(courseId));
}
复制代码

这里也可以不在外面定义 keySet,直接在 for 里面改成:

for (String courseID: courses.keySet()) {
}
复制代码
  • 第二种,去取这个 EntrySet,然后直接用每一个 Entry 来 getKey 和 getValue:
// 遍历 Map 法2:就用 entrySet
System.out.println("用 EntrySet 来遍历:");
Set<Map.Entry<String,String>> kvs = courses.entrySet();
for (Iterator iterator2 = kvs.iterator(); iterator2.hasNext();) {
    Map.Entry e = (Map.Entry) iterator2.next();
    System.out.println(e.getKey() + ": " + e.getValue());
}
复制代码

对 Map 遍历的代码,运行结果如下:

迭代时候删除要用 Iterator?

遍历时就删除:

System.out.println("遍历完就删除, 这个就显得有点诡异");
int n = ids.size();
for (int i=0; i<n; i++) {
    System.out.println(ids.get(0));
    System.out.println(ids.toString());
    ids.remove(0);
}
复制代码

就直接用上面初始化后的例子。只是一开始把 size 存起来。不然 size 会随着 list 删除一个元素而改变。 每次先打印一下要删的元素,再打一下当前的 list 状态。 运行结果:

推荐版写法:

也就是用 Iterator 来实现,在遍历有条件的删除:

// 推荐的写法:
System.out.println(ids.toString());
ids.add("wait remove 1");
ids.add("wait remove 2");
ids.add("wait remove 3");
System.out.println(ids.toString());
System.out.println("推荐写法:");
Iterator iterator1 = ids.iterator();
while(iterator1.hasNext()) {
    String obj = (String) iterator1.next();
    System.out.println(obj);
    if (obj.contains("1")) {
        iterator1.remove();
    }
}
System.out.println("end"+ids.toString());
复制代码

运行结果:

写一下还是更能加深自己的学习理解。继续,开启下一个知识点!冲冲冲 ~

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言
    友情链接