您好,登錄后才能下訂單哦!
這篇文章主要講解了Java實(shí)現(xiàn)儲(chǔ)存對(duì)象并按對(duì)象某屬排序的方法,內(nèi)容清晰明了,對(duì)此有興趣的小伙伴可以學(xué)習(xí)一下,相信大家閱讀完之后會(huì)有幫助。
在編程的時(shí)候,經(jīng)常會(huì)出現(xiàn)對(duì)某一種類的對(duì)象們按照某屬性進(jìn)行自定義的排序,比如:學(xué)生對(duì)象按照age大小排序。
有一種方法就是把a(bǔ)ge單獨(dú)提出來(lái)排好序,然后按照ages數(shù)組的順序把students重存一次。但是這樣太繁瑣了,有沒(méi)有更好的方法呢?
有滴~
第一種,可以實(shí)現(xiàn)邊添加邊排序,需要用到TreeSet。
第二種,用數(shù)組存放對(duì)象們,但是不需單獨(dú)取出某屬性排列好再重存,而是在原數(shù)組上用比較器重新排一次序。需要用到Arrays.sort(arr,comparator)。
第三種,用集合類中的list的子類存放對(duì)象們,然后排序。需要用到Collections.sort(list,comparator)。
以下分別討論:
一、TreeSet
創(chuàng)建:
序號(hào) | 構(gòu)造函數(shù)的說(shuō)明 |
---|---|
1 | TreeSet ()
此構(gòu)造函數(shù)構(gòu)造空樹(shù)集,將在根據(jù)其元素的自然順序按升序排序。 |
2 | TreeSet (集合 c)
此構(gòu)造函數(shù)生成樹(shù)的集合,它包含的元素的集合 c。 |
3 | TreeSet (比較器 comp)
此構(gòu)造函數(shù)構(gòu)造一個(gè)空樹(shù)集,將根據(jù)給定的比較器進(jìn)行排序。 |
增:
boolean | add(E e) 將指定的元素添加到這套,如果它已不存在。 |
boolean | addAll(Collection<? extends E> c) 在加入這一組指定的集合中添加的所有元素。 |
刪:
boolean | remove(Object o) 從這一組中移除指定的元素,如果它存在。 |
void | clear() 從這一組中移除所有元素。 |
查:
Comparator<? super E> | comparator() 返回用于排序在這集,或空元素,如果這套使用自然排序其元素的比較。 |
boolean | contains(Object o) 如果此集合包含指定的元素,則返回true 。 |
boolean | isEmpty() 如果此集不包含任何元素,則返回true 。 |
Iterator<E> | iterator() 返回迭代器中這套以升序排序的元素。 |
| |
int | size() 在這套 (其基數(shù)) 中返回的元素的數(shù)目。 |
|
遍歷:通過(guò)迭代器遍歷。
Iterator it=treeset.iterator(); while(it.hasNext()){ //操作當(dāng)前結(jié)點(diǎn)。 }
代碼實(shí)現(xiàn):
TreeSet是一個(gè)有序集合,TreeSet中的元素將按照升序排列。
TreeSet存儲(chǔ)對(duì)象的時(shí)候, 可以排序, 其中Integer有默認(rèn)排序方法, String有默認(rèn)排序方法,,而自定義的類對(duì)象存儲(chǔ)的時(shí)候則沒(méi)有順序,需要自定義排序算法。
如果想把自定義類的對(duì)象存入TreeSet進(jìn)行排序,或者對(duì)int,String對(duì)象想定義自己的排序方法,有以下兩種方法:
排序的第一種方式:
讓元素自身具備比較性。讓元素實(shí)現(xiàn)Comparable接口,覆蓋compareTo方法,在方法內(nèi)定義比較算法, 根據(jù)大小關(guān)系, 返回正數(shù)負(fù)數(shù)或零。在使用TreeSet存儲(chǔ)對(duì)象的時(shí)候, add()方法內(nèi)部就會(huì)自動(dòng)調(diào)用compareTo()方法進(jìn)行比較, 根據(jù)比較結(jié)果使用二叉樹(shù)形式進(jìn)行存儲(chǔ)。
排序的第二種方式:
自定義比較器。 定義一個(gè)類實(shí)現(xiàn)Comparator接口,覆蓋compare方法。將該Comparator接口子類對(duì)象傳遞給TreeSet集合構(gòu)造函數(shù)。
第一種:類定義時(shí)實(shí)現(xiàn)Comparable接口,定義自身的比較算法。
此處以Person類為例,把人名和年齡作為對(duì)象屬性,存放進(jìn)treeset中,按照年齡的升/降序保存。
public class TreeSetTest { public static void main(String[] args) { TreeSet people=new TreeSet(); people.add(new Person("小明", 20)); people.add(new Person("小張", 30)); people.add(new Person("小劉", 18)); people.add(new Person("小林", 17)); people.add(new Person("小劉", 35)); Iterator it=people.iterator(); while(it.hasNext()){ System.out.println(it.next()); } } } class Person implements Comparable{ //定義類時(shí),實(shí)現(xiàn)比較接口 String name; int age; public Person() { } public Person(String name, int age) { this.name = name; this.age = age; } public String toString(){ return "姓名:"+name+",年齡:"+age; } /* compareTo(Object o):參數(shù)是從根節(jié)點(diǎn)開(kāi)始依次傳進(jìn)來(lái)的結(jié)點(diǎn),直到確定合適的位置用來(lái)安插新節(jié)點(diǎn)。 方法返回三個(gè)值,分別對(duì)應(yīng)三種動(dòng)作:返回1,則繼續(xù)遞進(jìn),把新結(jié)點(diǎn)與下一層的結(jié)點(diǎn)進(jìn)行比較; 返回0,則該屬性值不足以決定兩結(jié)點(diǎn)位置區(qū)別,再定義其他屬性的比較算法來(lái)進(jìn)一步比較兩對(duì)象; 返回-1,則新結(jié)點(diǎn)優(yōu)先級(jí)大于當(dāng)前層,往上一層比較; */ public int compareTo(Object o) { Person curr=(Person) o; //int result = this.age<curr.age?1:(this.age==curr.age?0:-1);//降序排列:新插入結(jié)點(diǎn)與當(dāng)前比較層結(jié)點(diǎn)的屬性比較,小則返回1,繼續(xù)往下一層比較 int result = this.age>curr.age?1:(this.age==curr.age?0:-1);//升序排列:新插入結(jié)點(diǎn)與當(dāng)前比較層結(jié)點(diǎn)的屬性比較,大則返回1,繼續(xù)往下一層比較 if(result==0){ result=this.name.compareTo(curr.name);//age相同時(shí),則以姓名的字母序來(lái)排列。前面說(shuō)過(guò),int、string類型是有默認(rèn)排列算法的,所以此處直接用 } return result; } }
第二種:定義Comparator接口的實(shí)現(xiàn)類(比較器),在類中定義對(duì)象的比較算法。在創(chuàng)建Treeset時(shí)把比較器對(duì)象傳進(jìn)去。
public class TreeSetTest { /** * @param args the command line arguments */ public static void main(String[] args) { TreeSet people=new TreeSet(new MyComparator());//把比較器對(duì)象作為T(mén)reeSet的構(gòu)造函數(shù)參數(shù) people.add(new Person("小明", 20)); people.add(new Person("小張", 30)); people.add(new Person("小劉", 18)); people.add(new Person("小林", 17)); people.add(new Person("小劉", 35)); Iterator it=people.iterator();//用迭代器遍歷treeset while(it.hasNext()){ System.out.println(it.next()); } } } class Person { String name; int age; public Person() { } public Person(String name, int age) { this.name = name; this.age = age; } public String toString(){ return "姓名:"+name+",年齡:"+age; } } class MyComparator implements Comparator{//實(shí)現(xiàn)Comparator接口,自定義比較器,實(shí)現(xiàn)compare方法定義比較算法 /* compare(o1,o2):參數(shù)o1是待插入的結(jié)點(diǎn),o2是從樹(shù)根節(jié)點(diǎn)逐層遍歷下來(lái)的結(jié)點(diǎn),用于當(dāng)前比較。 方法返回三個(gè)值,分別對(duì)應(yīng)三種動(dòng)作:返回1,則繼續(xù)遞進(jìn),把新結(jié)點(diǎn)與下一層的結(jié)點(diǎn)進(jìn)行比較; 返回0,則該屬性值不足以決定兩結(jié)點(diǎn)位置區(qū)別,再定義其他屬性的比較算法來(lái)進(jìn)一步比較兩對(duì)象; 返回-1,則新結(jié)點(diǎn)優(yōu)先級(jí)大于當(dāng)前層,往上一層比較; */ public int compare(Object o1, Object o2) { Person p1=(Person)o1; Person p2=(Person)o2; int result=p1.age<p2.age?1:(p1.age==p2.age?0:-1);//降序排列 //int result=p1.age<p2.age?1:(p1.age==p2.age?0:-1);//升序排列 if(result==0){ result=p1.name.compareTo(p2.name); } return result; } }
二、用數(shù)組存放對(duì)象,用比較器改變sort()排序方法。
數(shù)組本身有默認(rèn)的排序方法,針對(duì)int、string等基本類型有默認(rèn)的sort()方法。而針對(duì)類對(duì)象的排序,可以給sort()方法傳進(jìn)一個(gè)比較器對(duì)象,賦予其排序的算法。
public class ArraysTest { public static void main(String[] args) { Person[] people=new Person[5]; people[0]=(new Person("小明", 20)); people[1]=(new Person("小張", 30)); people[2]=(new Person("小劉", 18)); people[3]=(new Person("小林", 17)); people[4]=(new Person("小劉", 35)); Arrays.sort(people,new MyCompare());//傳進(jìn)來(lái)一個(gè)比較器對(duì)象,使數(shù)組按比較器定義的規(guī)則來(lái)排序 for(Person i:people){ System.out.println(i); } } } class Person { String name; int age; public Person() { } public Person(String name, int age) { this.name = name; this.age = age; } public String toString(){ return "姓名:"+name+",年齡:"+age; } } class MyCompare implements Comparator<Person>{//定義比較器 /* 重寫(xiě)比較方法compare(o1,o2): 方法傳進(jìn)來(lái)兩個(gè)對(duì)象,用兩個(gè)對(duì)象的某屬性進(jìn)行對(duì)比,返回一個(gè)int。 int>0,則o1排在o2后面; int<0,則o1排在o2前面; int=0,則維持原相對(duì)位置,即原來(lái)存放時(shí)o1、o2的前后地址順序。 */ public int compare(Person o1, Person o2) { int result; if(o1.age>o2.age){ result=1; } else if(o1.age<o2.age){ result=-1; } else{ result=0; } return result; } }
第三種:用list的子類:Vector、ArrayList存放對(duì)象們,調(diào)用Collections.sort(list,comparator)方法進(jìn)行排序。
public class CollectionsTest { public static void main(String[] args) { Vector<Person> people=new Vector<>();//用向量保存對(duì)象 //ArrayList<Person> people=new ArrayList<>()://用ArrayList保存對(duì)象。 people.add(new Person("小明", 20)); people.add(new Person("小張", 30)); people.add(new Person("小劉", 18)); people.add(new Person("小林", 17)); people.add(new Person("小劉", 35)); Collections.sort(people,new MyComparator());//調(diào)用方法進(jìn)行排序 Iterator it=people.iterator(); while(it.hasNext()){ System.out.println(it.next()); } } } class Person { String name; int age; public Person() { } public Person(String name, int age) { this.name = name; this.age = age; } public String toString(){ return "姓名:"+name+",年齡:"+age; } } class MyComparator implements Comparator<Person>{//實(shí)現(xiàn)Comparator接口,自定義比較器,實(shí)現(xiàn)compare方法定義比較算法 /* compare(o1,o2):方法傳進(jìn)兩個(gè)對(duì)象,根據(jù)某屬性進(jìn)行比較,返回一個(gè)int值。 int>0,o1排在o2后; int<0,o1排在o2前; int=0,維持原來(lái)存放時(shí)的相對(duì)位置。 */ public int compare(Person p1, Person p2) { int result=p1.age<p2.age?1:(p1.age==p2.age?0:-1);//降序排列 //int result=p1.age<p2.age?1:(p1.age==p2.age?0:-1);//升序排列 if(result==0){ result=p1.name.compareTo(p2.name); } return result; } }
看完上述內(nèi)容,是不是對(duì)Java實(shí)現(xiàn)儲(chǔ)存對(duì)象并按對(duì)象某屬排序的方法有進(jìn)一步的了解,如果還想學(xué)習(xí)更多內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。