<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    for 與 foreach 的區別

    VSole2022-04-16 15:01:11

    之前有一個同事突然我問了我一個問題,說在foreach當中能不能刪除list里面的元素,我當時大概說了一下是否能刪除,以及原因;接下來我們來探討一下是否能夠如此;

    (1)遍歷元素

    首先,我們一一段代碼為例:

    String[] array = {"1", "2", "3"};
    for (String i : array) {
        System.out.println(i);
    }
    
    ArrayList list = new ArrayList<>();
    list.add("111");
    list.add("222");
    list.add("333");
    for (String i : list) {
        System.out.println(i);
    }
    

    遍歷后結果如下:

    1
    2
    3
    111
    222
    333
    

    結果毫無疑問。

    我們再來看看編譯后的源碼(idea自帶,在target包里打開你的類源碼文件即可):

    String[] array = new String[]{"1", "2", "3"};
    String[] var2 = array;
    int var3 = array.length;
    
    for(int var4 = 0; var4 < var3; ++var4) {
        String i = var2[var4];
        System.out.println(i);
    }
    
    ArrayList list = new ArrayList();
    list.add("111");
    list.add("222");
    list.add("333");
    Iterator var7 = list.iterator();
    
    while(var7.hasNext()) {
        String i = (String)var7.next();
        System.out.println(i);
    }
    

    可見,遍歷數組使用的是原始for循環,集合的話使用的是Iterator迭代器。

    (2)刪除元素

    哦的k!接下來我們來刪除元素:

    使用for循環:
    ArrayList list = new ArrayList<>();
    list.add("111");
    list.add("222");
    list.add("333");
    log.info(list.toString());
    for (int i = 0; i     list.remove("222");
    }
    
    log.info(list.toString());
    

    結果:

    11:11:52.532 [main] INFO com.xiaolinge.com.hello.HelloWord - [111, 222, 333]
    11:11:52.539 [main] INFO com.xiaolinge.com.hello.HelloWord - [111, 333]
    

    顯然成功!

    使用foreach:
    ArrayList list = new ArrayList<>();
    list.add("111");
    list.add("222");
    list.add("333");
    log.info(list.toString());
    for (String i : list) {
      list.remove("222");
    }
    log.info(list.toString());
    

    結果:

    11:50:48.333 [main] INFO com.xiaolinge.com.hello.HelloWord - [111, 222, 333]
    Exception in thread "main" java.util.ConcurrentModificationException
     at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)
     at java.util.ArrayList$Itr.next(ArrayList.java:859)
     at com.xiaolinge.com.hello.HelloWord.main(HelloWord.java:30)
    

    顯然木有成功!

    原因:

    迭代器內部的每次遍歷都會記錄List內部的modcount當做預期值,然后在每次循環中用預期值與List的成員變量modCount作比較,但是普通list.remove調用的是List的remove,這時modcount++,但是iterator內記錄的預期值=并沒有變化,所以會報錯。

    如果想要刪除元素的話需要使用迭代器內部的remove方法:

    ArrayList list = new ArrayList<>();
    list.add("111");
    list.add("222");
    list.add("333");
    log.info(list.toString());
    Iterator it = list.iterator();
    while (it.hasNext()){
        String next = it.next();
        //if外使用list的remove方法還是會報錯的
        if(next.equals("222")){
            it.remove();//這里使用的是迭代器里面的remove()方法,
            // 當然如果使用list的remove方法在此刪除質地感元素的話是成功的,比如:list.remove("222")
        }
    }
    log.info(list.toString());
    

    結果:

    12:06:14.042 [main] INFO com.xiaolinge.com.hello.HelloWord - [111, 222, 333]
    12:06:14.046 [main] INFO com.xiaolinge.com.hello.HelloWord - [111, 333]
    

    (3)修改元素

    使用原始for:
    ArrayList list = new ArrayList<>();
    list.add("111");
    list.add("222");
    list.add("333");
    log.info(list.toString());
    for (int i = 0; i     list.set(i,"444");
    }
     log.info(list.toString());
    

    結果:

    12:12:56.910 [main] INFO com.xiaolinge.com.hello.HelloWord - [111, 222, 333]
    12:12:56.915 [main] INFO com.xiaolinge.com.hello.HelloWord - [444, 444, 444]
    

    哦的k!可以修改元素;

    使用foreach:
    ArrayList list = new ArrayList<>();
     list.add("111");
     list.add("222");
     list.add("333");
     log.info(list.toString());
    for (String i : list) {
         i="444";
     }
      log.info(list.toString());  
    

    結果:

    12:34:47.207 [main] INFO com.xiaolinge.com.hello.HelloWord - [111, 222, 333]
    12:34:47.211 [main] INFO com.xiaolinge.com.hello.HelloWord - [111, 222, 333]
    

    看到咯,不行的哦。

    辣么,修改元素不行,修改元素的屬性可不可以呢?讓我們來看下吧。


    (4)foreach修改元素屬性

    (for就不測試了)

    創建一個學生類:

    public class Student {
            private int age;
            public int getAge() {
                return age;
            }
            public void setAge(int age) {
                this.age = age;
            }
            public String getName() {
                return name;
            }
            public void setName(String name) {
                this.name = name;
            }
            private String name;
            public Student(){};
            public Student(int age,String name){
                this.age=age;
                this.name=name;
            }
        } 
    

    哦的k,接下來測試代碼:

     Student student=new Student(1,"huge");
            Student student1=new Student(1,"xiaoyao");
            List studentList=new ArrayList();
            studentList.add(student);
            studentList.add(student1);
            System.out.println(student.getName());
            System.out.println(student1.getName());
            for(Student stu:studentList)
            {
                stu.setName("jingtian");
            }
            System.out.println(student.getName());
            System.out.println(student1.getName());
    

    結果:

    huge
    xiaoyao
    jingtian
    jingtian
    

    484很神奇!修改不了對象,卻可以修改對象的屬性。

    stringarraylist
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    APP協議分析心得
    2023-07-18 09:23:41
    對脫殼流程有不明白的可參考我之前寫的文章:[原創]ART環境下dex加載流程分析及frida dump dex方案。var magic_Hex = [0x64, 0x65, 0x78, 0x0a, 0x30, 0x33, 0x35, 0x00];var dex_path = "/data/data/" + apk_Name + "/" + dex_size + ".dex";
    ArrayList是線程不安全的,于是JDK新增加了一個線程并發安全的List——CopyOnWriteList,中心思想就是copy-on-write,簡單來說是讀寫分離:讀時共享、寫時復制(原本的array)更新(且為獨占式的加鎖),而我們下面分析的源碼具體實現也是這個思想的體現。 繼承體系:
    獲取到類之后,我們就可以通過反射來間接調用里面的方法,獲取里面的變量等。
    for 與 foreach 的區別
    2022-04-16 15:01:11
    之前有一個同事突然我問了我一個問題,說在foreach當中能不能刪除list里面的元素,我當時大概說了一下是否能刪除,以及原因;接下來我們來探討一下是否能夠如此;
    前言本次分析使用了ChatGPT進行輔助分析,大大提升了工作效率,很快就分析出木馬的工作流程和構造出利用方式。
    1 背之前講過“不推薦使用屬性拷貝工具”,薦直接定義轉換類和方法使用 IDEA 插件自動填充 get / set 函數。接下來我們看 Spring 的 BeanUtils 的屬性拷貝會存在啥問題:import?大家運行上述示例時,會發生類型轉換異常。打斷點可以看到,屬性拷貝之后 B 類型的 second 對象中 ids 仍然為 Integer 類型:如果不轉換為字符串,直接進行打印,并不會報錯。使用CGlib 在不定義Converter 的情況下也會遇到類似問題:import?可以成功的將 A 中 List 轉為 B 中的 List 類型。
    每次聊到代碼優化,都會有很多人說理論、架構、核心思路,其實我覺得代碼優化這事說簡單了很簡單,說復雜了吧它也有一定的難度,但是我覺得有一個良好的編碼習慣很重要,下面分享一下14個springboot項目中優化代碼的小技巧,讓代碼優化跟容易,就像完成一件小事。
    Android 應用gl,使用了加固i,老版本的應用gl是js源碼,新版本更新后,剛開始以為是加密了源碼,分析后才知道是使用了Hermes優化引擎。Hermes優化的優化效果如下:優化前:優化后:二、前期準備2.1 繞過root檢測應用gl使用了加固i,在被root 的手機上運行,閃退。繞過方法也很簡單,在magisk的設置中,開啟遵守排除列表,然后在配置排除列表中選擇應用gl。
    每天運行導數任務,把現有的千萬量級的底池數據(Hive 表)導入到 Clickhouse 中,后續使用 CK 表進行數據篩選。
    前兩天做了一個導入的功能,導入開始的時候非常慢,導入2w條數據要1分多鐘,后來一點一點的優化,從直接把list懟進Mysql中,到分配把list導入Mysql中,到多線程把list導入Mysql中。 時間是一點一點的變少了。非常的爽,最后變成了10s以內。 下面就展示一下過程。
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类