1.Iterator 迭代器
Collection 集合元素的通用获取方式: 在取元素之前先要判断集合中有没有元素, 如果有, 就把这个元素取出来, 继续在判断, 如果还有就再取出出来. 一直把集合中的所有元素全部取出. 这种取出方式专业术语称为迭代.
集合中把这种取元素的方式描述在 Iterator 接口中.
常用的方法:
判断集合中是否有下一个元素可以替代, 如果可以替代则返回 true:hasNext() / boolean;
返回迭代的下一个元素并把指针向下移一位: naxt() / E;
Collection 接口描述了一个抽象方法 iterator 方法, 所有 Collection 子类都实现了这个方法, 并且有自己的迭代形式.
代码演示迭代器:
- //1, 创建集合对象.
- Collection<String> coll = new ArrayList<String>();
- coll.add("abc1");
- coll.add("abc2");
- coll.add("abc3");
- coll.add("abc4");
- //2. 获取容器的迭代器对象. 通过 iterator 方法.
- Iterator it = coll.iterator();
- //3, 使用具体的迭代器对象获取集合中的元素. 参阅迭代器的方法
- while(it.hasNext()){
- System.out.println(it.next());
- }
- /*
- 迭代器 for 循环的形式的使用
- for (Iterator it = coll.iterator(); it.hasNext(); ) {
- System.out.println(it.next());
- }
- */
在进行集合元素取出时, 如果集合中已经没有元素了, 还继续使用迭代器的 next 方法, 将会发生 java.util.NoSuchElementException 没有集合元素的错误.
集合元素的向下转型
集合中存储其实都是对象的地址.
存储时提升了 Object. 取出时要使用元素的特有内容, 必须向下转型.
代码演示:
- Collection coll = new ArrayList();
- coll.add("abc");
- coll.add("aabbcc");
- coll.add(1);
- Iterator it = coll.iterator();
- while (it.hasNext()) {
- // 由于元素被存放进集合后全部被提升为 Object 类型
- // 当需要使用子类对象特有方法时, 需要向下转型
- String str = (String) it.next();
- System.out.println(str.length());
- }
注意: 如果集合中存放的是多个对象, 这时进行向下转型会发生类型转换异常.
提示: Iterator 接口也可以使用 <> 来控制迭代元素的类型的. 代码演示如下:
- Collection<String> coll = new ArrayList<String>();
- coll.add("abc");
- coll.add("aabbcc");
- coll.add("cat");
- Iterator<String> it = coll.iterator();
- while (it.hasNext()) {
- String str = it.next();
- // 当使用 Iterator<String > 控制元素类型后, 就不需要强转了. 获取到的元素直接就是 String 类型
- System.out.println(str.length());
- }
2. 增强 for 循环
增强 for 循环是 JDK1.5 以后出来的一个高级 for 循环, 专门用来遍历数组和集合的. 它的内部原理其实是个 Iterator 迭代器, 所以在遍历的过程中, 不能对集合中的元素进行增删操作.
格式为:
- for(元素的数据类型 变量 : Collection 集合 or 数组){
- }
代码演示:
它用于遍历 Collection 和数组. 通常只进行遍历元素, 不要在遍历的过程中对集合元素进行增删操作.
练习一: 遍历数组 int[] arr = new int[]{11,22,33};
- for (int n : arr) {
- // 变量 n 代表被遍历到的数组元素
- System.out.println(n);
- }
练习二: 遍历集合
- Collection<String> coll = new ArrayList<String>();
- coll.add("a1");
- coll.add("a2");
- coll.add("a3");
- coll.add("a4");
- for(String str : coll){
- // 变量 Str 代表被遍历到的集合元素
- System.out.println(str);
- }
与普通 for 循环的区别:
新 for 循环必须有被遍历的目标. 目标只能是 Collection 或者是数组.
遍历数组时, 如果仅为遍历, 可以使用增强 for 如果要对数组的元素进行 操作, 使用老式 for 循环可以通过角标操作.
3. 泛型
由于集合中什么类型的元素都可以存储. 导致取出时, 如果出现强转就会引发运行时 ClassCastException. 怎么来解决这个问题呢? 使用集合时, 必须明确集合中元素的类型. 这种方式称为: 泛型.
我们在集合中会大量使用到泛型, 这里来完整地学习泛型知识.
泛型, 用来灵活地将数据类型应用到不同的类, 方法, 接口当中. 将数据类型作为参数进行传递.
定义格式:
修饰符 class 类名<代表泛型的变量> { }
代码演示:
API 中的 ArrayList 集合:
- class ArrayList<E>{
- public boolean add(E e){
- }
- public E get(int index){
- }
- }
使用格式: 创建对象时, 确定泛型的类型
例如, ArrayList<String> list = new ArrayList<String>();
此时, 变量 E 的值就是 String 类型
- class ArrayList<String>{
- public boolean add(String e){
- }
- public String get(int index){
- }
- }
例如, ArrayList<Integer> list = new ArrayList<Integer>();
此时, 变量 E 的值就是 Integer 类型
- class ArrayList<Integer>{
- public boolean add(Integer e){
- }
- public Integer get(int index){
- }
- }
泛型接口定义格式:
修饰符 interface 接口名<代表泛型的变量> { }
代码演示:
API 中的 Iterator 迭代器接口
- public interface Iterator<E> {
- public abstract E next();
- }
使用格式:
1, 定义类时确定泛型的类型
例如
- public final class Scanner implements Iterator<String> {
- public String next(){
- }
- }
泛型通配符
泛型是在限定数据类型, 当在集合或者其他地方使用到泛型后, 那么这时一旦明确泛型的数据类型, 那么在使用的时候只能给其传递和数据类型匹配的类型, 否则就会报错.
定义方法时, 根本无法确定具体集合中的元素类型是什么. 为了解决这个 "无法确定具体集合中的元素类型" 问题, java 中, 为我们提供了泛型的通配符<?>.
代码演示:
- public static void printCollection(Collection<?> list) {
- Iterator<?> it = list.iterator();
- while (it.hasNext()) {
- System.out.println(it.next());
- }
- }
实现了可迭代任意元素类型集合的方法
使用泛型的通配符后, 只能使用 Object 类中的共性方法, 集合中元素自身方法无法使用.
泛型限定
如果想要对被打印的集合中的元素类型进行限制, 只在指定的一些类型, 进行打印. 怎么做呢?
要解决这个问题, 我们就要学习泛型的限定.
限定泛型的上限:
格式:? extends E
? 代表接收 E 类型或者 E 的子类型的元素
例如, 泛型限定为:? extends Person
则 ? 代表接收 Person 类型或者 Person 子类型的元素
限定泛型的下限:
格式:? super E
? 代表接收 E 类型或者 E 的父类型的元素
例如, 泛型限定为:? super Student
则 ? 代表接收 Student 类型或者 Student 父类型的元素
代码演示:
- public static void printCollection(Collection<? extends Person> list) {
- Iterator<? extends Person> it = list.iterator();
- while (it.hasNext()) {
- System.out.println(it.next());
- }
- }
来源: http://www.bubuko.com/infodetail-3194198.html