List 的removeall需要重寫equals才有效

removeAll() 失效重現(xiàn)

今天做一個批量刪除的功能滋迈,我使用了 List.removeAll()這個方法罪郊,但是該代碼執(zhí)行前后版确,被操作的列表的 size 并沒由發(fā)生改變扣囊。排查了一下,是因為兩個列表中存儲對象不同的原因绒疗。

實體類:

public class Bean {

    private int id;
    private String name;
    private String address;

    public Bean(int id, String name, String address) {
        this.id = id;
        this.name = name;
        this.address = address;
    }
}

構建場景:

ArrayList<Bean>  allStudents = new ArrayList<>();
     ArrayList<Bean>  boyStudents = new ArrayList<>();


     for (int i = 0; i < 10 ; i++) {
         Bean  bean = new Bean(i,"name is "+i,"address is "+i);
         allStudents.add(bean);

     }


     for (int i = 0; i < 5 ; i++) {
         Bean  bean = new Bean(i,"name is "+i,"address is "+i);
         boyStudents.add(bean);

     }

      System.out.println("allStudents.size()------before-------------->"+allStudents.size());
      System.out.println("remove result : "+allStudents.removeAll(boyStudents));
      System.out.println("allStudents.size()-------after-------------->"+allStudents.size());

輸出結果是:

allStudents.size()------before-------------->10
remove result : false
allStudents.size()-------after-------------->10

但是侵歇,換 String 對象執(zhí)行 removeAll() 竟然可以成功!

因為操作對象不同吓蘑,這是一個很簡單的原因惕虑,但是接下來要實驗的另一個小例子坟冲,絕對讓你非常吃驚,我們講Bean 替換成 String 字符串試一下溃蔫。

ArrayList<Bean>  allStudents = new ArrayList<>();
       ArrayList<Bean>  boyStudents = new ArrayList<>();
       for (int i = 0; i < 10 ; i++) {
           Bean  bean = new Bean(i,"name is "+i,"address is "+i);
           allStudents.add(bean);

       }


       for (int i = 0; i < 5 ; i++) {
           Bean  bean = new Bean(i,"name is "+i,"address is "+i);
           boyStudents.add(bean);

       }

       System.out.println("allStudents.size()------before-------------->"+allStudents.size());
       System.out.println("remove result : "+allStudents.removeAll(boyStudents));
       System.out.println("allStudents.size()-------after-------------->"+allStudents.size());

輸出結果是 :

allStudents.size()------before-------------->10
remove result : true
allStudents.size()-------after-------------->5

揭開這一切的面紗

從打印結果很明白的看到健提,removeAll() 成功執(zhí)行。String也是對象伟叛,為什么會這樣私痹?代碼不會說謊,我們去源碼中去尋找答案统刮。
從源碼中發(fā)現(xiàn)紊遵,ArrayList 執(zhí)行 removeAll() 方法流程如下圖所示:

通過控制變量法分析,很容易就聚焦到 equals()這個方法侥蒙,這個方法是 Object 的方法,默認實現(xiàn)是比較對象在內存的地址暗膜。

public boolean equals(Object obj) {
       return (this == obj);
}

再看一下 String 中 equals() 方法,重寫了 Object 的這個方法鞭衩,不再是比較地址学搜,而是比較字符串是否相同。

public boolean equals(Object anObject) {
     if (this == anObject) {
         return true;
     }
     if (anObject instanceof String) {
         String anotherString = (String) anObject;
         int n = count;
         if (n == anotherString.count) {
             int i = 0;
             while (n-- != 0) {
                 if (charAt(i) != anotherString.charAt(i))
                         return false;
                 i++;
             }
             return true;
         }
     }
     return false;
 }

這樣的話论衍,引發(fā)了一個思考瑞佩,也就是說,如果自定義對象饲齐,重寫 equals() 中的實現(xiàn)钉凌,也是可以實現(xiàn)非相同對象的情況下咧最,成功 removeAll()的捂人。這里我用 上面例子的 Bean 實體類簡單實驗一下:

public class Bean {

    private int id;
    private String name;
    private String address;

    public Bean(int id, String name, String address) {
        this.id = id;
        this.name = name;
        this.address = address;
    }


    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Bean bean = (Bean) o;

        if (id != bean.id) return false;
        if (!name.equals(bean.name)) return false;
        return address.equals(bean.address);

    }

    @Override
    public int hashCode() {
        int result = id;
        result = 31 * result + name.hashCode();
        result = 31 * result + address.hashCode();
        return result;
    }
}

再次執(zhí)行第一個例子的程序,ArrayList 成功 removeAll矢沿,打印信息如下:

allStudents.size()------before-------------->10
remove result : true
allStudents.size()-------after-------------->5
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末滥搭,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子捣鲸,更是在濱河造成了極大的恐慌瑟匆,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,252評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件栽惶,死亡現(xiàn)場離奇詭異愁溜,居然都是意外死亡,警方通過查閱死者的電腦和手機外厂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評論 3 399
  • 文/潘曉璐 我一進店門冕象,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人汁蝶,你說我怎么就攤上這事渐扮。” “怎么了?”我有些...
    開封第一講書人閱讀 168,814評論 0 361
  • 文/不壞的土叔 我叫張陵拯钻,是天一觀的道長躁倒。 經常有香客問我,道長耻讽,這世上最難降的妖魔是什么察纯? 我笑而不...
    開封第一講書人閱讀 59,869評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮针肥,結果婚禮上捐寥,老公的妹妹穿的比我還像新娘。我一直安慰自己祖驱,他們只是感情好握恳,可當我...
    茶點故事閱讀 68,888評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著捺僻,像睡著了一般乡洼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上匕坯,一...
    開封第一講書人閱讀 52,475評論 1 312
  • 那天束昵,我揣著相機與錄音,去河邊找鬼葛峻。 笑死锹雏,一個胖子當著我的面吹牛,可吹牛的內容都是我干的术奖。 我是一名探鬼主播礁遵,決...
    沈念sama閱讀 41,010評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼采记!你這毒婦竟也來了佣耐?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,924評論 0 277
  • 序言:老撾萬榮一對情侶失蹤唧龄,失蹤者是張志新(化名)和其女友劉穎兼砖,沒想到半個月后,有當地人在樹林里發(fā)現(xiàn)了一具尸體既棺,經...
    沈念sama閱讀 46,469評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡讽挟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,552評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了丸冕。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片耽梅。...
    茶點故事閱讀 40,680評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖晨仑,靈堂內的尸體忽然破棺而出褐墅,到底是詐尸還是另有隱情拆檬,我是刑警寧澤,帶...
    沈念sama閱讀 36,362評論 5 351
  • 正文 年R本政府宣布妥凳,位于F島的核電站竟贯,受9級特大地震影響,放射性物質發(fā)生泄漏逝钥。R本人自食惡果不足惜屑那,卻給世界環(huán)境...
    茶點故事閱讀 42,037評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望艘款。 院中可真熱鬧持际,春花似錦、人聲如沸哗咆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽晌柬。三九已至姥份,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間年碘,已是汗流浹背澈歉。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留屿衅,地道東北人埃难。 一個月前我還...
    沈念sama閱讀 49,099評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像涤久,于是被迫代替她去往敵國和親涡尘。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,691評論 2 361

推薦閱讀更多精彩內容

  • 1. Java基礎部分 基礎部分的順序:基本語法拴竹,類相關的語法悟衩,內部類的語法剧罩,繼承相關的語法栓拜,異常的語法,線程的語...
    子非魚_t_閱讀 31,664評論 18 399
  • 寒煙飄零閱讀 141評論 0 0
  • 非暴力溝通的一個重要因素是感受惠昔。感受不僅要求我們體會他人的感受幕与,還要求我們有能力正確表達我們自己的感受。這兩者是相...
    晰言閱讀 202評論 0 1
  • 唐舞麟被謝邂拉著回到了學校镇防,第二天……“跟我打啦鸣!”“……”“我要跟你打!”“……”謝邂依舊在找唐舞麟打架来氧,可他卻選...
    蘇浩櫻丶淡殤閱讀 577評論 0 1