一、集合的遍历
这里我们引申一个问题,怎么对集合进行遍历,对于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);
}