在我们java中我们存储数据的方式,在我们之前学习中数组是可以存储我们的数据的,但是数组存储数据有一些弊端,灵活性不强,存储数据类型有限,灵活性不强这一点主要是体现在两个方面:一方面数组的长度是自定义后就不改变的,而且必须提前定义,另一方面,增加和修改数组的数据过程是很复杂的。而且数组只能存储同一类型的数据,为了解决这个弊端我们提出了集合这个概念,集合分为两大类一个是实现Collection接口的类,Map类俩种,集合有什么好处呢,集合的长度是可变的,而且它可以存储多种数据类型,而且它提供了许多便利的方法,之后我们会依次的用代码实例展示,并且分析源码,首先我们先看一下这两大类的体系图。
Collection类:
Map类:
这里我们大概了解一下它的数据形式,List和Set接口实现的是单列集合,Map接口实现的是双列集合即K-V,这里的K指的是Key,这里的V指的是Value,我们又称它为键值对。
这里我们先演示一下Collection接口实现类ArrayList类的相关方法以及注释:
import java.util.ArrayList;
import java.util.List;
public class Array {@SuppressWarnings({"all"})public static void main(String[] args) {List list = new ArrayList();// add:添加单个元素list.add("jack");list.add(10);//list.add(new Integer(10))list.add(true);System.out.println("list=" + list);// remove:删除指定元素//list.remove(0);//删除第一个元素list.remove(true);//指定删除某个元素System.out.println("list=" + list);// contains:查找元素是否存在System.out.println(list.contains("jack"));//T// size:获取元素个数System.out.println(list.size());//2// isEmpty:判断是否为空System.out.println(list.isEmpty());//F// clear:清空list.clear();System.out.println("list=" + list);// addAll:添加多个元素ArrayList list2 = new ArrayList();list2.add("红楼梦");list2.add("三国演义");list.addAll(list2);System.out.println("list=" + list);// containsAll:查找多个元素是否都存在System.out.println(list.containsAll(list2));//T// removeAll:删除多个元素list.add("聊斋");list.removeAll(list2);System.out.println("list=" + list);//[聊斋]}
}
但是如果我们想取出集合中的元素该怎么办呢,我们是否能用之前学的for循环遍历集合将集合取出,答案是可以的,因为集合也是提供size()和get()方法的,但是我们还会发现Collection实现了一个叫Iterable这个接口,这里的Iterable接口说明集合可以使用迭代器来进行对元素的提取。
首先我们先了解一下迭代器的使用原理是什么,因为Collection实现了迭代器的接口所以实现Collection接口的所有类都有个迭代器方法iterator()我们先来看一下如何使用它,我们用代码实例来解释:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Array {@SuppressWarnings({"all"})public static void main(String[] args) {List list = new ArrayList();list.add("jack");list.add("mack");list.add("孙悟空");list.add("猪八戒");list.add("唐僧");list.add("中国队长");Iterator iterator = list.iterator();//首先通过该方法得到一个迭代器//通过iterator.hasNext()该方法来判断集合是否有下一个元素,返回布尔类型while (iterator.hasNext()){//通过iterator.next();将next这个指针下移,并返回现有集合的元素Object abj = iterator.next();System.out.println(abj);}//如果我们需要二次遍历该集合直接使用while的话我们会发现根本提取不了元素while (iterator.hasNext()){Object abj = iterator.next();System.out.println(abj);}}
}
为什么会出现该现象,这里解释一下原理,因为你在上次while循环的时候next的指针已经到元素的末尾,所以你下次循环的时候has.next()方法判断是否有下一个元素的时候返回的就是false根本不会进行循环,那如果我们就想二次遍历集合怎么办,我们只需要重置一下迭代器即可:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Array {@SuppressWarnings({"all"})public static void main(String[] args) {List list = new ArrayList();list.add("jack");list.add("mack");list.add("孙悟空");list.add("猪八戒");list.add("唐僧");list.add("中国队长");Iterator iterator = list.iterator();//首先通过该方法得到一个迭代器//通过iterator.hasNext()该方法来判断集合是否有下一个元素,返回布尔类型while (iterator.hasNext()){//通过iterator.next();将next这个指针下移,并返回现有集合的元素Object abj = iterator.next();System.out.println(abj);}//如果我们需要二次遍历该集合直接使用while的话我们会发现根本提取不了元素iterator = list.iterator();//重置迭代器来解决上述问题while (iterator.hasNext()){Object abj = iterator.next();System.out.println(abj);}}
}
这里我们就解决了上述问题,当然大家也是可以重新得到一个新的迭代器来进行遍历。
还有一种方法是for-each来进行遍历,这种for循环又称增强for循环,但是这里有个有意思的点,待会我们来看一下增强for循环的源码是什么我们先来演示一下:
import java.util.ArrayList;
import java.util.List;
public class Array {@SuppressWarnings({"all"})public static void main(String[] args) {List list = new ArrayList();list.add("jack");list.add("mack");list.add("孙悟空");list.add("猪八戒");list.add("唐僧");list.add("中国队长");for (Object o :list) {System.out.println(o);}}
}
我们会看到增强for跟迭代器的效果是一样的
接下来我们来看一下增强for的源码到底长什么样
我们发现在Degbug增强for的时候发现进入了这个方法上,但是发现又有点眼熟,这不就是迭代器嘛,其实我们增强for的元素遍历就是调用的迭代器,换句话说增强for的本质就是迭代器,所以能有增强for方法的,一定能用迭代器遍历,这就是本次的全部内容,接下来的文章会比较繁琐,因为HashMap,HashSet,Hashtable等等这些类的内容以及源码;理解起来会比较麻烦,但是我也会尽力去写好。