zoukankan      html  css  js  c++  java
  • 探究map,list,for

    从map中取数据的几种不同方式

     1 HashMap<String, String> stringStringHashMap = new HashMap<>();
     2         stringStringHashMap.put("a","1");
     3         stringStringHashMap.put("b","2");
     4         stringStringHashMap.put("c","3");
     5         stringStringHashMap.put("d","4");
     6 
     7         long l1 = System.currentTimeMillis();
     8         for (String s:stringStringHashMap.values()){
     9             System.out.println("这里是: "+ s);
    10         }
    11 //        Iterator var6 = stringStringHashMap.values().iterator();
    12 //编译后的代码实际上是这样,使用迭代器
    13 //      while(var6.hasNext()) {
    14     //    String s = (String)var6.next();
    15     //    System.out.println("这里是: " + s);
    16 //}
    17         long l2 = System.currentTimeMillis();
    18         System.out.println(l2-l1);
    19         System.out.println();
    20 
    21         long l3 = System.currentTimeMillis();
    22         for (Map.Entry<String,String> entry:stringStringHashMap.entrySet()){
    23             System.out.println("k: "+entry.getKey()+" v: "+entry.getValue());
    24         }
    25         Iterator var10 = stringStringHashMap.entrySet().iterator();
    26 
    27 //        while(var10.hasNext()) {
    28 //            Entry<String, String> entry = (Entry)var10.next();
    29 //            System.out.println("k: " + (String)entry.getKey() + " v: " + (String)entry.getValue());
    30 //        }
    31         long l4 = System.currentTimeMillis();
    32         System.out.println(l4-l3);
    33         System.out.println();
    34 
    35 
    36         Iterator<Entry<String, String>> iterator = stringStringHashMap.entrySet().iterator();
    37         while (iterator.hasNext()){
    38             Entry<String, String> next = iterator.next();
    39             System.out.println(next.getValue());
    40         }
    41 //        while(iterator.hasNext()) {
    42 //            Entry<String, String> next = (Entry)iterator.next();
    43 //            System.out.println((String)next.getValue());这里编译是做的类型转换的
    44 //        }
    45         System.out.println();
    46 
    47         stringStringHashMap.forEach((key,value)->{
    48             var a=value;
    49             System.out.println(a);
    50         });
    51 //        stringStringHashMap.forEach((key, value) -> {
    52 //            System.out.println(value);  没有什么用的var一行可以直接省略
    53 //        });
    54 
    55         // 1.Map entries
    56         Consumer<Entry<String, String>> action = System.out::println;
    57         stringStringHashMap.entrySet().forEach(action);
    58 //        PrintStream var10000 = System.out;
    59 //        System.out.getClass();
    60 //        Consumer<Entry<String, String>> action = var10000::println;
    61 //        前三行反而会将那一行拆开
    62 //        stringStringHashMap.entrySet().forEach(action);
    63 
    64         // 2.Map keys
    65         Consumer<String> actionKeys = System.out::println;
    66         stringStringHashMap.keySet().forEach(actionKeys);
    67 
    68         // 3. Map values
    69         Consumer<String> actionValues = System.out::println;
    70         stringStringHashMap.values().forEach(actionValues);
    71 
    72         System.out.println("----");
    View Code

    map的for循环都是用到了迭代器

    遍历数组和集合的区别

     1 String[] array = {"1", "2", "3"};
     2         for (String i : array) {
     3             System.out.println(i);
     4         }
     5 //        for(int var4 = 0; var4 < var3; ++var4) {
     6 //            String i = var2[var4];
     7 //            System.out.println(i);
     8 //        }
     9         
    10 
    11         ArrayList<String> list = new ArrayList<>();
    12         list.add("111");
    13         list.add("222");
    14         list.add("333");
    15         for (String i : list) {
    16             System.out.println(i);
    17         }
    18 //        Iterator var17 = list.iterator();
    19 //
    20 //        while(var17.hasNext()) {
    21 //            String i = (String)var17.next();
    22 //            System.out.println(i);
    23 //        }
    View Code

     可见,遍历数组使用的是原始for循环,集合的话使用的是Iterator迭代器。

    foreach里面是否可以删除添加list中的元素---》

    foreach不可以删除/修改/增加 集合元素,而for可以

     1 ArrayList<String> lista = new ArrayList<>();
     2         lista.add("111");
     3         lista.add("222");
     4         lista.add("333");
     5 
     6 //        log.info(list.toString());
     7         System.out.println(lista.toString());
     8         System.out.println(lista.getClass());
     9         for (int i = 0; i < lista.size(); i++) {
    10             lista.remove("222");
    11             System.out.println(i);
    12         }
    13         System.out.println(lista.toString());
    14         System.out.println(lista.getClass());
    15         System.out.println("----");
    16 
    17         ArrayList<String> listb = new ArrayList<>();
    18         listb.add("111");
    19         listb.add("222");
    20         listb.add("333");
    21         System.out.println(listb.toString());
    22 
    23         for (String i : listb) {
    24 //            listb.remove("222");
    25 
    26 
    27 //            不要在foreach循环里进行元素的remove/add操作,remove元素请使用Iterator方式。
    28 //
    29 //            Negative example:
    30 //            List<String> originList = new ArrayList<String>();
    31 //            originList.add("22");
    32 //            for (String item : originList) {
    33 //                //warn
    34 //                list.add("bb");
    35 //            }
    36 //
    37 //
    38 //
    39 //            Positive example:
    40 //            Iterator<Integer> it=b.iterator();
    41 //            while(it.hasNext()){
    42 //                Integer temp =  it.next();
    43 //                if (delCondition) {
    44 //                    it.remove();
    45 //                }
    46 //            }
    47             System.out.println(i);
    48         }
    49         System.out.println(listb.toString());
    50 //        java.util.ConcurrentModificationException 报错,
    51 
    52         System.out.println("========");
    53 
    54         ArrayList<String> listc = new ArrayList<>();
    55         listc.add("111");
    56         listc.add("222");
    57         listc.add("333");
    58         System.out.println(listc);
    59         Iterator<String> it = listc.iterator();
    60         while (it.hasNext()) {
    61             String next = it.next();
    62 
    63 //            it.remove();//这里使用的是迭代器里面的remove()方法,
    64             if (next.equals("222")) {
    65                 it.remove();//这里使用的是迭代器里面的remove()方法,
    66 //                // 当然如果使用list的remove方法在此删除质地感元素的话是成功的,比如:list.remove("222")
    67 //            }
    68             }
    69             System.out.println(listc);
    70 
    71 
    72         }
    73     }
    View Code

    https://blog.csdn.net/weixin_44056462/article/details/90769772

    这里面需要理解一点底层的源码思想

    https://blog.csdn.net/qq_40521656/article/details/90749927

     1 ArrayList<String> list = new ArrayList<>();
     2         list.add("111");
     3         list.add("222");
     4         list.add("333");
     5 //        log.info(list.toString());
     6         System.out.println(list);
     7         for (String i : list) {
     8             i="444";
     9         }
    10         System.out.println(list);
    11 输出无变换
    View Code

    foreach不能修改集合的元素 

     1  Student student=new Student(1,"huge");
     2         Student student1=new Student(1,"xiaoyao");
     3         List<Student> studentList=new ArrayList<Student>();
     4         studentList.add(student);
     5         studentList.add(student1);
     6         System.out.println(student.getName());
     7         System.out.println(student1.getName());
     8         for(Student stu:studentList)
     9         {
    10             stu.setName("jingtian");
    11         }
    12         System.out.println(student.getName());
    13         System.out.println(student1.getName());
    View Code

    但是可以修改对象的属性

    1、for与foreach都可以遍历数组/集合,不过for则在较复杂的循环中效率更高。
    2、foreach不可以删除/修改集合元素,而for可以
    3、foreach和for都可以修改duixiang里面的属性
    所以相比较下来for循环更为灵活。

    从这里我们可以学习迭代器模式https://www.runoob.com/design-pattern/iterator-pattern.html, 这也是好处啊:迭代器模式将存储数据和遍历数据的职责分离

    还可以学习到数组虽然可以用foreach,但实际上编译的时候又成了普通的forhttps://www.cnblogs.com/slwenyi/p/6393366.html

    观察使用迭代器成功删除集合元素的时候

    第一次         第二次

       注意这里,删除元素后,游标减1,lastr直接成-1,期望次数加1  第三次

    注意:如果代码中的remove用的不是迭代器的删除功能,会导致一个提前退出的问题,listc.remove("222");,而将原来的集合增加一个元素,在用这个就会报错ConcurrentModificationException,因为---》下图中modCount(记录了对集合修改的次数)的值不等于expectedModCount(通过迭代器对集合修改的次数

    https://www.cnblogs.com/YYCat/p/4675084.html

    可以看源码

    iterator的next和remove,以及check

     1  @SuppressWarnings("unchecked")
     2         public E next() {
     3             checkForComodification();
     4             int i = cursor;
     5             if (i >= size)
     6                 throw new NoSuchElementException();
     7             Object[] elementData = ArrayList.this.elementData;
     8             if (i >= elementData.length)
     9                 throw new ConcurrentModificationException();
    10             cursor = i + 1;
    11             return (E) elementData[lastRet = i];
    12         }
    13  final void checkForComodification() {
    14             if (modCount != expectedModCount)
    15                 throw new ConcurrentModificationException();
    16         }
    17 
    18 public void remove() {
    19             if (lastRet < 0)
    20                 throw new IllegalStateException();
    21             checkForComodification();
    22 
    23             try {
    24                 ArrayList.this.remove(lastRet);  注意这个实际是数组自己的remove
    25                 cursor = lastRet;
    26                 lastRet = -1;
    27                 expectedModCount = modCount;
    28             } catch (IndexOutOfBoundsException ex) {
    29                 throw new ConcurrentModificationException();
    30             }
    31         }
    View Code

    数组的remove方法

     1 public E remove(int index) {
     2         rangeCheck(index);
     3 
     4         modCount++;
     5         E oldValue = elementData(index);
     6 
     7         int numMoved = size - index - 1;
     8         if (numMoved > 0)
     9             System.arraycopy(elementData, index+1, elementData, index,
    10                              numMoved);
    11         elementData[--size] = null; // clear to let GC do its work
    12 
    13         return oldValue;
    14     }
    View Code

    可以理解为,这也就体现了迭代器的作用

    反正别人这样说https://blog.csdn.net/layman1024/article/details/76103793,,我还没看到真的源码,线程,还没验证过,所以这里也不确定。

    回归正题,取map中的值有哪些方式,他们的区别是啥,for和foreach,1.8的呢,能充分利用多核,实现真正的并行,如果数据量不大,只能起到简化代码的作用,而数据量大的时候,其威力就展现了。

    for和foreach的效率……:(1)for是使用下标(偏移量)定位的.
    (2)foreach应该是使用类似循环子的机构
    (3)对随机访问效率高的ArrayList. 使用下标访问效率本身很高.foreach内部的循环子直接封装下标,自己实现的for比foreach更直接,效率稍高些,但差别不会太大,仍然在一个数量级上。 (4)如果使用插入和删除效率高的LinkedList,for基于下标访问会每次从头查询,效率会很低.foreach循环子使用高效的地址运算,效率会高.其差距将很大,完全不在一个数量级别.如果数组很大,差别可能会几百甚至上千倍.

    为什么呢,下标定位,for配数组,链表结构foreach配链表,就这样撒。

  • 相关阅读:
    arrow
    简单库函数
    计算机视觉从入门到放肆
    合并排序算法
    React应用数据传递的方式
    发布一个npm package
    绝对路径/相对路径/根路径
    常见的数据处理方法
    从设计稿到实现React应用(分类数据处理)
    提高React组件的复用性
  • 原文地址:https://www.cnblogs.com/woainixxx/p/13185587.html
Copyright © 2011-2022 走看看