前言:
未来这个词听上去就是美好,可是你别忘了呀,每一个我们所期待的美好未来,都必须有一个努力的现在!!!
我们上一篇聊到了java之集合,这一篇我们聊一下增强for和迭代器,针对于以下的概念,都会有实体例子配合着,给大家演示,希望给历险中的你带来一些帮助!!!
一.增强for介绍
for-each循环是jdk1.5引入的新的语法功能。并不是所有东西都可以使用这个循环的。可以看下Iterable接口的注释,它说明了除了数组外,其他类想要使用for-each循环必须实现这个接口。这一点表明除了数组外的for-each可能底层是由迭代器实现的。
Iterable接口在1.8之前只有一个方法,Iterator<T>
iterator(),此方法返回一个迭代器。由于更早出现的Collection接口中早就有了这个同样的方法,所以只需要让Collection接口继承Iterable接口,基于Collection的集合类就可以不做任何更改就使用for-each循环。
对于数组,因为数组不实现Iterable接口,它的for-each实现原理应该和Collection不一样。
1.1缺点:
1、对于数组,不能方便的访问下标值;
2、对于集合,与使用Interator相比,不能方便的删除集合中的内容(在内部也是调用Interator).
除了简单遍历并读取其中的内容外,不建议使用增强的for循环。
1.3.知识点详解
1.3.1遍历数组
语法为:
for (Type value : array) {
expression value;
}
代码演示 :
以前我们这样写:
public class Test{
public static void main(String args[]){
int[]array = {1,2,5,8,9};
int total = 0;
for(int i = 0; i < array.length; i++){
total += array[i];
}
System.out.println(total);
}
}
现在我们只需这样写(和以上写法是等价的):
public class Test{
public static void main(String args[]){
int[]array = {1,2,5,8,9};
inttotal = 0;
for(int n : array){
total+= n;
}
System.out.println(total);
}
}
这种循环的缺点是:
(1)只能顺次遍历所有元素,无法实现较为复杂的循环,如在某些条件下需要后退到之前遍历过的某个元素
(2)循环变量(i)不可见,如果想知道当前遍历到数组的第几个元素
1.4遍历集合
语法为:
for
(Type value : Iterable) {
expression
value;
}
注意:增强for循环遍历的集合必须是实现Iterable接口的。
代码演示:
以前我们这样写:
void someFunction (){
List list = new ArrayList();
list.add("Hello");
list.add("Java");
list.add("World!");
Strings = "";
for(Iterator iter = list.iterator(); iter.hasNext();){
String temp= (String) iter.next();
s+= temp;
}
System.out.println(s);
}
现在我们这样写:
void someFunction (){
List list = new ArrayList();
list.add("Hello");
list.add("Java");
list.add("World!");
Strings = "";
for(Object o : list){
Stringtemp = (String) o;
s+= temp;
}
System.out.println(s);
}
1.5代码训练
增强型的for循环优点主要体现在集合中
1.5.1题目
使用增强for循环遍历字符串“hello World!”。
1.5.2实验步骤
使用String类的toCharArray()方法
代码演示:
package com.Test;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Main {
private final static String name = "磊哥的java历险记-@51博客";
public static void main(String args[]){
String s = "Hello World!";
for(char ch:s.toCharArray()){
System.out.println(ch);
}
System.out.println(name);
}
}
二.迭代器介绍
迭代器(iterator)有时又称游标(cursor)是程序设计的软件设计模式,可在容器(container,例如链表或阵列)上遍访的接口,设计人员无需关心容器的内容。
迭代器(iterator)是一种对象,它能够用来遍历标准模板库容器中的部分或全部元素,每个迭代器对象代表容器中的确定的地址。迭代器修改了常规指针的接口,所谓迭代器是一种概念上的抽象:那些行为上像迭代器的东西都可以叫做迭代器。然而迭代器有很多不同的能力,它可以把抽象容器和通用算法有机的统一起来。
2.1内容
集合用来持有数据,一定会设计出对数据的增、删、改、查四个常用方法,而查是集合中最常用的功能。Collection接口继承了Iterable接口,具备了可迭代功能iterator方法,该方法用于迭代集合。所以,所有单列集合由于是Collection的直接或间接实现类,均具有该方法。
这里涉及到以下内容共同完成集合的迭代:
Collection接口的iterator方法,所以单列集合实现类均有该方法
iterator方法的返回值类型Iterator接口类型
Iterator接口的两个方法:hasNext与next方法
2.2迭代常规步骤
(1)通过集合获取这个集合的迭代器
(2)结合使用迭代器的hashNext与next完成集合迭代
代码演示:
package com.Test;
import java.util.ArrayList;
import java.util.Iterator;
public class Main {
private final static String name = "磊哥的java历险记-@51博客";
public static void main(String args[]){
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("磊哥的java历险记-@51博客");
//返回迭代器
Iterator<String> iterator = arrayList.iterator();
//调用hasNext与next完成集合迭代
while(iterator.hasNext()) {
String string= iterator.next();
System.out.println(string);
}
}
}
2.3Collection接口的Iterator
方法声明为:
Iterator<集合中数据类型> iterator()
用来返回专属于该集合对象的迭代器对象(Iterator的子类对象)。
2.4.Iterator接口
该接口规定了迭代集合所需要的方法
2.5.Iterator接口的两个方法:hasNext与next方法
Iterator规定了两个方法,集合对象产生的迭代器对象正是通过这两个方法帮助集合进行迭代工作的。
调用迭代器的hasNext方法判断是否有下一个元素
调用迭代器的next获取下一个元素
2.6.迭代集合元素图解:
2.7代码演示
package com.Test;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/*
* Iterator<E> iterator() 返回在此 collection 的元素上进行迭代的迭代器。
*
* Iterator 就是帮你去做遍历集合操作 .
*
* iterator() 返回的就是 Iterator接口的子类对象.
*/
public class Main {
public static void main(String[] args) {
Collection c = new ArrayList();
c.add("磊哥的java历险记-@51博客");
c.add("888");
// 遍历集合. 获取其中每一个元素.
// 1.获取迭代器对象 .
Iterator iterator= c.iterator(); // Iterator 接口 指向 子类对象.
// 2.调用迭代器的方法,获取集合中的元素.
// Object next = iterator.next();
// System.out.println(next);
//
// Object next2 = iterator.next();
// System.out.println(next2);
//
// Object next3 = iterator.next();
// System.out.println(next3);
//
// Object next4 = iterator.next();
// System.out.println(next4);
//
// Object next5 = iterator.next(); //NoSuchElementException
// System.out.println(next5);
while(iterator.hasNext()){
Object next = iterator.next();
System.out.println(next);
}
}
}
2.8迭代器遍历集合总结
package com.Test;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/*
* 1.hasNext 方法和 next方法说明 . 遍历之前,有一个指针指向初始位置,第一个元素的前面,
* hasNext,判断是否在指针后面有元素,有返回true ,没有返回false.
* 如果有 , 就可以通过 next() 获取下一个元素了.
* 2.syso(c); 我也能看所有的元素, 那我为什么还要遍历呢?
*
* 3.toString() 在哪重写的呢? 你管的着么!! 要找找他爹,他爷爷
*
*/
public class Main {
public static void main(String[] args) {
Collection c = new ArrayList<>();
c.add("磊哥的java历险记-@51博客");
c.add("666");
// 遍历集合
// 1.获取迭代器
Iterator iterator = c.iterator();
// 2.通过迭代器获取元素 .
while(iterator.hasNext()) { // 是否有下一个.
Object next = iterator.next(); // 获取下一个元素
System.out.println(next);
}
}
}
2.9并发修改异常(扩展)
迭代的常规用法中我们要尽量避免在迭代过程中为集合添加/删除数据。否则会报错,原因是Java抛出了并发修改异常。
迭代过程中并发修改异常的原因为迭代器中”记忆”的集合长度与集合中实际长度不同,而导致出现索引与实际元素不符甚至无限循环的情况发生。
所以在使用Iterator时,避免类似操作,for循环底层为迭代器实现,所以也需要避免类似操作。
有些迭代器避免了这样的问题,如ListIterator,但该类并不通用也不常用,实际开发中很少使用,只需要简单了解。
java中提供了很多个集合,它们在存储元素时,采用的存储方式不同。我们要取出这些集合中的元素,可通过一种通用的获取方式来完成。
代码演示:
package com.Test;
import java.util.*;
/*
* 并发修改异常:当你 遍历集合并操作集合,添加或者移除元素的使用,可能会报出并发修改异常.
* 处理方式:添加,移除 ,使用迭代器的方法. 迭代器中的remove.
* 查看异常信息: 第一行是异常的说明 _空指针 ,角标越界, 并发.....
* 详细异常信息, 从下往上看, 能看懂哪行就是你发生异常的地方,基本上就是你写错代码.
* Iterator.next()继续迭代的时候报错, 那么我们提供一种解决方案, 可以修改,但是不再遍历集合.
*
* 解决方案:
* 1.采用 Iterator中的方法去操作集合 -- 推荐 !
* 2.使用非Iterator中的方法操作, 那么再操作之后 ,加 break;
*
*/
public class Main {
public static void main(String[] args) {
Collection<String> c = new ArrayList<String>();
c.add("磊哥的java历险记-@51博客");
c.add("666");
c.add("I Love Java");
System.out.println(c);
Iterator<String> iterator = c.iterator();
while(iterator.hasNext()) {
String string= iterator.next();
// 如果存在666 ,那么添加一个888
if(string.equals("666")) {
c.add("888");
break;
}
}
System.out.println(c); //java.util.ConcurrentModificationException 并发修改异常
List l = new ArrayList<>();
ListIterator listIterator= l.listIterator();
}
}
结语:
没人会一直顺利,愿你更加强大,然后终于有一天,可以笑着讲述那些曾让你哭的瞬间!
因为自身原因,很长一段时间没有更新文章,后面我会接着之前的大纲更新的,希望能够帮助看到我文章的兄弟们,特别是初学者!感谢大家持续关注! ! !