JAVA集合-迭代器

一、集合的遍历

这里我们引申一个问题,怎么对集合进行遍历,对于List很简单,因为它天生就支持下标访问

public class ListTest {
    public static void main(String[] args) {
        public List<String> names = new ArrayList<>();
        names.add("lucy");
        names.add("tom");
        names.add("jerry");
        for (int i = 0; i < names.size(); i++) {
            System.out.println(names.get(i));
        }
    }
}

但是对于hashmap和hashset无法遍历,它们没有下标,这里就需要使用迭代器了。

二、迭代器

我们看一下迭代器的这个接口,他张这个样子

public interface Iterator<E> {
    // 是不是有下一个
    boolean hasNext();
    // 拿到下一个
    E next();
    // 你可以继承重写这个方法,否则将抛出异常
    default void remove() {
        throw new UnsupportedOperationException("remove");
    }
}
2.1、List迭代器
public class ArrayListTest {
    public static ArrayList<Integer> arrayList = new  ArrayList<>();
    public static void main(String[] args) {
        arrayList.add(1);
        arrayList.add(2);
        arrayList.add(3);
        Iterator<Integer> iterator = arrayList.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }
}
2.2、Set迭代器
public class SetTest {
    public static HashSet<Integer> set = new HashSet<>();

    public static void main(String[] args) {
        set.add(1);
        set.add(1);
        set.add(2);
        set.add(3);
        Iterator<Integer> iterator = set.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }
}
2.3、Map迭代器
public class MapTest {
    public static HashMap<String,String> map = new HashMap<>();
    
    public static void main(String[] args) {
        map.put("a","a");
        map.put("b","b");
        map.put("c","c");
        Set<Map.Entry<String,String>> set = map.entrySet();
        Iterator<Map.Entry<String,String>> iterator = set.iterator();
        while (iterator.hasNext()){
            Map.Entry<String,String> next = iterator.next();
            System.out.println(next.getKey());
            System.out.println(next.getValue());
        }
    }
}

这里想这样一个问题,我们为什么不能这么写

while (iterator.hasNext()){
    System.out.println(iterator.next().getKey());
    System.out.println(iterator.next().getValue());
}

因为这样相当于在一次遍历中,游标向后移动了两位。

当然我们也可以只遍历key,通过key找到value,但是这样的效率比较低。

public class MapTest {
    public static HashMap<String,String> map = new HashMap<>();

    public static void main(String[] args) {
        map.put("a","a");
        map.put("b","b");
        map.put("c","c");
        Set<String> key = map.keySet();
        Iterator<String> iterator = key.iterator();
        while (iterator.hasNext()){
            String next = iterator.next();
            System.out.println(next);
            System.out.println(map.get(next));
        }
    }
}

三、增强For循环

Java提供了一种语法糖去帮助我们遍历,叫增强for循环,List、Set都可以使用这种方式进行遍历:

List,Set:

for (String name : names){
        System.out.println(name);
}

Map:

for (Map.Entry<String,String> entry : map.entrySet()){
    System.out.println(entry.getKey());
    System.out.println(entry.getValue());
}

增强for循环其实也是使用了迭代器,只是一种语法糖,用起来简单而已。

四、迭代中删除元素

我们现在试想这样一个场景,我们需要遍历元素,然后删除我们不想要的元素我们该怎么办

4.1、for循环中删除
package com;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Iterator;

public class ArrayListTest {
    public static ArrayList<Integer> arrayList = new  ArrayList<>();
    @Test
    public void add() {
        arrayList.add(1);
        arrayList.add(2);
        arrayList.add(3);
        arrayList.add(3);
        arrayList.add(4);
    }
    @Test
    public void delete(int val){
        for (int i = 0; i < arrayList.size(); i++) {
            if(arrayList.get(i) == val){
                arrayList.remove(i);
            }
        }
        System.out.println(arrayList);
    }

    public static void main(String[] args) {
        ArrayListTest arrayListTest = new ArrayListTest();
        arrayListTest.add();
        System.out.println(arrayList);
        arrayListTest.delete(3);
    }
}

我们发现我们只删除了一个3,第二个3我们并没有删除掉,这是因为我们删除第一个3的时候已经导致第二个3来到了第一个3的位置,而游标已经后移。我们可以用一个小技巧来解决这个问题,就是删除以后游标不动(回调指针)。

public class ArrayListTest {
    public static ArrayList<Integer> arrayList = new  ArrayList<>();
    @Test
    public void add() {
        arrayList.add(1);
        arrayList.add(2);
        arrayList.add(3);
        arrayList.add(3);
        arrayList.add(4);
    }
    @Test
    public void delete(int val){
        for (int i = 0; i < arrayList.size(); i++) {
            if(arrayList.get(i) == val){
                arrayList.remove(i);
                // 保持i的位置不动
                i--;
            }
        }
        System.out.println(arrayList);
    }

    public static void main(String[] args) {
        ArrayListTest arrayListTest = new ArrayListTest();
        arrayListTest.add();
        System.out.println(arrayList);
        arrayListTest.delete(3);
    }
}

其实还有第二个办法,就是逆序遍历

4.2、逆序遍历

这样也能解决问题,但是指针对于set和list

public void delete(){
    for (int i = arrayList.size()-1; i >= 0 ; i--) {
        if(arrayList.get(i) == 3){
        	arrayList.remove(i);
        }
    }
    System.out.println(arrayList);
}
4.3、迭代器中删除
public static void main(String[] args){
    Iterator<String> iterator = names.iterator();
    while (iterator.hasNext()){
        // 记住next(),只能调用一次,因为每次调用都会选择下一个
        String name = iterator.next();
        if("lucy".equals(name)){
            iterator.remove();
        }
    }
    System.out.println(names);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LyaJpunov

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值