簡(jiǎn)單的理解java集合中的HashSet和HashTree幾個(gè)重寫方法
Java中的set是無(wú)序的,但是是不可重復(fù)的
HashSet底層是哈希表,通過(guò)調(diào)用hashcode和equals方法實(shí)現(xiàn)去重
當(dāng)我們HashSet里面存的是字符串時(shí),就能默認(rèn)去重了,因?yàn)镾tring已經(jīng)重寫了hashcode和euqals方法
public static void main(String[] args) { HashSet<String> set = new HashSet(); set.add("java"); set.add("c"); set.add("php"); set.add("bigdata"); set.add("java"); //運(yùn)行結(jié)果,給去重了,而且是無(wú)序的 System.out.println(set);//[java, c, bigdata, php] } }
但是當(dāng)我們有類的時(shí)候,比如Person,Cat,Dog,我們自己寫的類,但是我們想按照自己制定的規(guī)則去重,就比如Person的姓名和年齡,因?yàn)镻erson類是我們自己建的,如果我們沒(méi)有重寫方法,就會(huì)去找Object的hashcode方法,這樣new Person()的hashcode就會(huì)不同,這樣每個(gè)都是一個(gè)新的,都會(huì)輸出,即使年齡和姓名一樣
public class Demo1 { public static void main(String[] args) { HashSet<Person> set1 = new HashSet<>(); set1.add(new Person("aing",50)); set1.add(new Person("bing",10)); set1.add(new Person("ding",20)); set1.add(new Person("ding",20)); //運(yùn)行結(jié)果是即使名字年齡一樣,也會(huì)輸出兩個(gè),我們?nèi)绻胍凑兆约旱囊?guī)則去重,這樣我們一定要重寫hashcode 和euqals方法 System.out.println(set1);//[Person{name='bing', age=10}, Person{name='ding', age=20}, Person{name='aing', age=50}, Person{name='ding', age=20}] } } class Person{ String name; int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
我們重寫hashcode方法,當(dāng)hashcode不一樣時(shí),就不會(huì)比較equals,直接就是不一樣,如果hashcode一樣,再比較equals方法
public class Demo1 { public static void main(String[] args) { HashSet<Person> set1 = new HashSet<>(); set1.add(new Person("aing",50)); set1.add(new Person("bing",10)); set1.add(new Person("ding",20)); set1.add(new Person("ding",20)); //根據(jù)年齡和姓名比較的 System.out.println(set1);//[Person{name='ding', age=20}, Person{name='aing', age=50}, Person{name='bing', age=10}] } } class Person{ String name; int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; return age == person.age && Objects.equals(name, person.name); } //和屬性關(guān)聯(lián),根據(jù)屬性的值比較,之所以讓age*100;是因?yàn)榕掠锌赡艹霈F(xiàn)這個(gè)name.hashCode()+age 和 下一個(gè)name.hashCode()+age加起來(lái)的值恰好相等,所以age*100,可以避免這種情況的發(fā)生 @Override public int hashCode() { //return Objects.hash(name, age); return name.hashCode()+age*100; } }
TreeSet底層是二叉樹,而且TreeSet還是有序的,在String中不僅重寫了hashcode,還要調(diào)用元素的compareTo方法, String類已經(jīng)實(shí)現(xiàn)了Comparable接口,并重寫 了compareTo方法,但是如果我們自己寫類的話,比如Person來(lái)說(shuō),如果想要按照自己的規(guī)則比,就要重寫hashcode方法和實(shí)現(xiàn)Comparable接口
public class Demo2 { public static void main(String[] args) { TreeSet<String> set = new TreeSet(); set.add("java"); set.add("c"); set.add("php"); set.add("bigdata"); set.add("java"); System.out.println(set);//[bigdata, c, java, php] } }
但是要是自己的類
會(huì)報(bào)錯(cuò)cannot be cast to java.lang.Comparable,因?yàn)镻erson會(huì)去找compareTo的方法,但是Person類沒(méi)有實(shí)現(xiàn)它,我們要去實(shí)現(xiàn)Comparable
public class Demo2 { public static void main(String[] args) { TreeSet<Person1> set1 = new TreeSet<>(); set1.add(new Person1("aing",50)); set1.add(new Person1("bing",10)); set1.add(new Person1("ding",20)); set1.add(new Person1("ding",20)); System.out.println(set1); } } class Person1{ String name; int age; public Person1(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Person1{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
這樣我們就可以實(shí)現(xiàn)有序了,根據(jù)我們的屬性
public class Demo2 { public static void main(String[] args) { TreeSet<Person1> set1 = new TreeSet<>(); set1.add(new Person1("aing",50)); set1.add(new Person1("bing",10)); set1.add(new Person1("ding",20)); set1.add(new Person1("ding",20)); System.out.println(set1); } } class Person1 implements Comparable{ String name; int age; public Person1(String name, int age) { this.name = name; this.age = age; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Person1 person1 = (Person1) o; return age == person1.age && Objects.equals(name, person1.name); } @Override public int hashCode() { return name.hashCode()+age*100; } @Override public String toString() { return "Person1{" + "name='" + name + '\'' + ", age=" + age + '}'; } //根據(jù)類的屬性進(jìn)行排序 @Override public int compareTo(Object o) { Person1 person = (Person1)o; int num = name.compareTo(person.name); return num==0?age-person.age:num; } }
到此這篇關(guān)于簡(jiǎn)單的理解java集合中的HashSet和HashTree幾個(gè)重寫方法的文章就介紹到這了,更多相關(guān)java HashSet和HashTree重寫內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Java?詳解Collection集合之ArrayList和HashSet
- Java多線程高并發(fā)中解決ArrayList與HashSet和HashMap不安全的方案
- Java基礎(chǔ)之詳解HashSet的使用方法
- java中HashSet的特點(diǎn)及實(shí)例用法
- Java HashSet(散列集),HashMap(散列映射)的簡(jiǎn)單介紹
- JAVA HashSet和TreeSet 保證存入元素不會(huì)重復(fù)的操作
- 實(shí)例講解Java HashSet
- Java HashSet集合存儲(chǔ)遍歷學(xué)生對(duì)象代碼實(shí)例
- Java?HashSet的Removals()方法注意事項(xiàng)
相關(guān)文章
JAVA 自定義線程池的最大線程數(shù)設(shè)置方法
這篇文章主要介紹了JAVA 自定義線程池的最大線程數(shù)設(shè)置方法,文中示例代碼非常詳細(xì),供大家參考和學(xué)習(xí),感興趣的朋友可以了解下2020-06-06Java和c語(yǔ)言隨機(jī)數(shù)Random代碼詳細(xì)
這篇文章主要介紹Java和c語(yǔ)言得隨機(jī)數(shù)Random,隨機(jī)數(shù)的用處在生活中比較少見,但是用處并不少,比如一些小游戲的制作等等。下面我們就一起來(lái)學(xué)習(xí)這篇關(guān)于Java和c隨機(jī)數(shù)Random得文章吧2021-10-10springboot通用分支處理超級(jí)管理員權(quán)限邏輯
這篇文章主要為大家介紹了springboot通用分支處理超級(jí)管理員的權(quán)限邏輯,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07JAVA實(shí)現(xiàn)圖書管理系統(tǒng)項(xiàng)目
相信每一個(gè)學(xué)生學(xué)編程的時(shí)候,應(yīng)該都會(huì)寫一個(gè)小項(xiàng)目——圖書管理系統(tǒng)。為什么這么說(shuō)呢?我認(rèn)為一個(gè)學(xué)校的氛圍很大一部分可以從圖書館的氛圍看出來(lái),而圖書管理系統(tǒng)這個(gè)不大不小的項(xiàng)目,接觸的多,也比較熟悉,不會(huì)有陌生感,能夠練手,又有些難度,所以我的小項(xiàng)目也來(lái)了2021-10-10Springboot實(shí)現(xiàn)動(dòng)態(tài)定時(shí)任務(wù)流程詳解
通過(guò)重寫SchedulingConfigurer方法實(shí)現(xiàn)對(duì)定時(shí)任務(wù)的操作,單次執(zhí)行、停止、啟動(dòng)三個(gè)主要的基本功能,動(dòng)態(tài)的從數(shù)據(jù)庫(kù)中獲取配置的定時(shí)任務(wù)cron信息,通過(guò)反射的方式靈活定位到具體的類與方法中2022-09-09java?JVM方法分派模型靜態(tài)分派動(dòng)態(tài)分派全面講解
這篇文章主要為大家介紹了java?JVM方法分派模型靜態(tài)分派動(dòng)態(tài)分派全面講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06