Java笔记_几种循环区别_codeJeseanL

Java循环分类

Iterator
for
foreach
Stream.forEach
  1. Java迭代器Iterator
    Iterator接口包含一个能够产生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());
    }
}

Iterator和for循环的区别
remove方法的区别: 调用remove方法后, list.size()大小发生变化.
for循环中remove后可能导致逻辑错误
Iterator循环中remove后不仅会删除元素, 还会维护一个标志, 用来记录目前是不是可删除状态, 所以重复删除就会报错.

/**
 * 删除元素
 */
public static void test() {
    List 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 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();
        }
    }
}

Iterator和for和foreach循环效率比较
ArrayList中的比较: ArrayList是通过动态数组来实现的, 支持随机访问, ArrayList中的迭代器(foreach也使用了迭代器来实现)其实也是通过数组名+下标来获取元素的, 只是多了一些逻辑代码, 所以会比直接get慢, 可以忽略.

public static void testFor() {
    List 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 list = new ArrayList();
    for (int i = 0; i < 5000000; i++) {
        list.add("list" + i);
    }
    //iterator循环
    long begin = System.currentTimeMillis();
    Iterator 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 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 list = new LinkedList();
    for (int i = 0; i < 100000; i++) {
        list.add("list" + i);
    }
    //iterator循环
    long begin = System.currentTimeMillis();
    Iterator 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)+"毫秒");
}

Stream.forEach
1)集合操作超过两个步骤,比如先filter再for each,适合用Stream方式。
2)任务较重,注重效能,希望并发执行,用Stream能隐式利用多线程技术。
3)采用函数式编程的编码风格可简化代码。

参考链接: [https://www.jianshu.com/p/b5dbf4d4ce4f]

你可能感兴趣的:(Java笔记_几种循环区别_codeJeseanL)