1、java循环分类
Iterator、for、foreach、Stream.forEach
2、java迭代器Iterator
Iterable接口包含一个能够产生Iterator的iterator()方法,任何实现Iterable接口的类,都可以进行循环遍历。
/**
* 迭代器 遍历list、map
*/
public static void test() {
List list = new ArrayList();
Map map = new HashMap();
for (int i = 0; i < 5; i++) {
list.add("list" + i);
map.put(i, "map" + i);
}
//遍历list
Iterator iterator_list = list.iterator();
while (iterator_list.hasNext()) {
String next = (String) iterator_list.next();
System.out.println(next);
}
//遍历map
Iterator iterator_map = map.entrySet().iterator();
while (iterator_map.hasNext()) {
Map.Entry next = (Map.Entry) iterator_map.next();
System.out.println(next.getValue());
}
}
3、Iterator和for循环的区别
remove方法的区别:调用remove方法后,list.size()的大小变化。
for循环中remove后可能导致逻辑错误。
Iterator循环中remove后不仅会删除元素,还会维护一个标志,用来记录目前是不是可删除状态,所以重复删除就会报错。
/**
* 删除元素
*/
public static void test() {
List<String> list = new ArrayList();
for (int i = 0; i < 5; i++) {
list.add("list" + i);
}
//for循环
for(int i = 0; i < list.size(); i ++){
System.out.println(list.get(i));
if("list2".equals(list.get(i))){
//由于删除了list2,list的大小变化,获导致list3不会被遍历到
list.remove(list.get(i));
}
}
List<String> list2 = new ArrayList();
for (int i = 0; i < 5; i++) {
list2.add("list" + i);
}
//Iterator
Iterator iterator = list2.iterator();
while (iterator.hasNext()) {
//iterator.remove(); //报错;不知道删谁
String next = (String) iterator.next();
System.out.println(next);
if("list2".equals(next)){
iterator.remove();
//重复删除会报错,目前是不可删除状态
//iterator.remove();
}
}
}
4、Iterator和for和foreach循环效率比较
ArrayList中的比较:ArrayList是通过动态数组来实现的,支持随机访问。ArrayList中的迭代器(foreach也是用了迭代器来实现)其实也是通过数组名+下标来获取元素的,只是多了一些逻辑代码,所以会比直接get慢,可以忽略。
public static void testFor() {
List<String> list = new ArrayList();
for (int i = 0; i < 5000000; i++) {
list.add("list" + i);
}
//for循环
int size = list.size();
long begin = System.currentTimeMillis();
for(int i = 0; i < size; i ++){
if("test".equals(list.get(i))){
System.out.println("我是不会被执行的");
}
}
long end = System.currentTimeMillis();
//执行5次分别是45、57、46、46、44
System.out.println("耗时"+(end-begin)+"毫秒");
}
/**
* 效率比较 iterator稍慢,差几毫秒已经是很多了
* 为什么慢,因为源码中其实也是通过数组名+下标来获取元素的,只是多了一些逻辑代码
*/
public static void testIterator() {
List<String> list = new ArrayList();
for (int i = 0; i < 5000000; i++) {
list.add("list" + i);
}
//iterator循环
long begin = System.currentTimeMillis();
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()){
if("test".equals(iterator.next())){
System.out.println("我是不会被执行的");
}
}
long end = System.currentTimeMillis();
//执行5次分别是48、52、54、47、63
System.out.println("耗时"+(end-begin)+"毫秒");
}
LinkedList中的比较:LinkedList是通过双向链表实现的,不支持随机访问。顺序访问会更快,所以迭代器会比直接get快很多。
/**
* 效率比较
*/
public static void testFor() {
List<String> list = new LinkedList<>();
for (int i = 0; i < 100000; i++) {
list.add("list" + i);
}
//for循环
int size = list.size();
long begin = System.currentTimeMillis();
for(int i = 0; i < size; i ++){
if("test".equals(list.get(i))){
System.out.println("我是不会被执行的");
}
}
long end = System.currentTimeMillis();
//执行3次分别是51307、48282、47405
System.out.println("耗时"+(end-begin)+"毫秒");
}
/**
* 效率比较 iterator快 ,LinkedList更适合顺序访问
*
*/
public static void testIterator() {
List<String> list = new LinkedList();
for (int i = 0; i < 100000; i++) {
list.add("list" + i);
}
//iterator循环
long begin = System.currentTimeMillis();
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()){
if("test".equals(iterator.next())){
System.out.println("我是不会被执行的");
}
}
long end = System.currentTimeMillis();
//执行3次分别是8、10、8
System.out.println("耗时"+(end-begin)+"毫秒");
}
5、Stream.forEach
1)集合操作超过两个步骤,比如先filter再for each,适合用Stream方式。
2)任务较重,注重效能,希望并发执行,用Stream能隐式利用多线程技术。
3)采用函数式编程的编码风格可简化代码。
了解Java 8 Stream详情