Java實現(xiàn)儲存對象并按對象某屬性排序的幾種方法示例
本文實例講述了Java實現(xiàn)儲存對象并按對象某屬性排序的幾種方法。分享給大家供大家參考,具體如下:
在編程的時候,經(jīng)常會出現(xiàn)對某一種類的對象們按照某屬性進行自定義的排序,比如:學(xué)生對象按照age大小排序。
有一種方法就是把age單獨提出來排好序,然后按照ages數(shù)組的順序把students重存一次。但是這樣太繁瑣了,有沒有更好的方法呢?
有滴~
第一種,可以實現(xiàn)邊添加邊排序,需要用到TreeSet。
第二種,用數(shù)組存放對象們,但是不需單獨取出某屬性排列好再重存,而是在原數(shù)組上用比較器重新排一次序。需要用到Arrays.sort(arr,comparator)。
第三種,用集合類中的list的子類存放對象們,然后排序。需要用到Collections.sort(list,comparator)。
以下分別討論:
一、TreeSet
創(chuàng)建:
| 序號 | 構(gòu)造函數(shù)的說明 |
|---|---|
| 1 | TreeSet ()
此構(gòu)造函數(shù)構(gòu)造空樹集,將在根據(jù)其元素的自然順序按升序排序。 |
| 2 | TreeSet (集合 c)
此構(gòu)造函數(shù)生成樹的集合,它包含的元素的集合 c。 |
| 3 | TreeSet (比較器 comp)
此構(gòu)造函數(shù)構(gòu)造一個空樹集,將根據(jù)給定的比較器進行排序。 |
增:
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ù)目。 |
|
遍歷:通過迭代器遍歷。
Iterator it=treeset.iterator();
while(it.hasNext()){
//操作當(dāng)前結(jié)點。
}
代碼實現(xiàn):
TreeSet是一個有序集合,TreeSet中的元素將按照升序排列。
TreeSet存儲對象的時候, 可以排序, 其中Integer有默認(rèn)排序方法, String有默認(rèn)排序方法,,而自定義的類對象存儲的時候則沒有順序,需要自定義排序算法。
如果想把自定義類的對象存入TreeSet進行排序,或者對int,String對象想定義自己的排序方法,有以下兩種方法:
排序的第一種方式:
讓元素自身具備比較性。讓元素實現(xiàn)Comparable接口,覆蓋compareTo方法,在方法內(nèi)定義比較算法, 根據(jù)大小關(guān)系, 返回正數(shù)負(fù)數(shù)或零。在使用TreeSet存儲對象的時候, add()方法內(nèi)部就會自動調(diào)用compareTo()方法進行比較, 根據(jù)比較結(jié)果使用二叉樹形式進行存儲。
排序的第二種方式:
自定義比較器。 定義一個類實現(xiàn)Comparator接口,覆蓋compare方法。將該Comparator接口子類對象傳遞給TreeSet集合構(gòu)造函數(shù)。
第一種:類定義時實現(xiàn)Comparable接口,定義自身的比較算法。
此處以Person類為例,把人名和年齡作為對象屬性,存放進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{ //定義類時,實現(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é)點開始依次傳進來的結(jié)點,直到確定合適的位置用來安插新節(jié)點。
方法返回三個值,分別對應(yīng)三種動作:返回1,則繼續(xù)遞進,把新結(jié)點與下一層的結(jié)點進行比較;
返回0,則該屬性值不足以決定兩結(jié)點位置區(qū)別,再定義其他屬性的比較算法來進一步比較兩對象;
返回-1,則新結(jié)點優(yōu)先級大于當(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é)點與當(dāng)前比較層結(jié)點的屬性比較,小則返回1,繼續(xù)往下一層比較
int result = this.age>curr.age?1:(this.age==curr.age?0:-1);//升序排列:新插入結(jié)點與當(dāng)前比較層結(jié)點的屬性比較,大則返回1,繼續(xù)往下一層比較
if(result==0){
result=this.name.compareTo(curr.name);//age相同時,則以姓名的字母序來排列。前面說過,int、string類型是有默認(rèn)排列算法的,所以此處直接用
}
return result;
}
}
第二種:定義Comparator接口的實現(xiàn)類(比較器),在類中定義對象的比較算法。在創(chuàng)建Treeset時把比較器對象傳進去。
public class TreeSetTest {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
TreeSet people=new TreeSet(new MyComparator());//把比較器對象作為TreeSet的構(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{//實現(xiàn)Comparator接口,自定義比較器,實現(xiàn)compare方法定義比較算法
/*
compare(o1,o2):參數(shù)o1是待插入的結(jié)點,o2是從樹根節(jié)點逐層遍歷下來的結(jié)點,用于當(dāng)前比較。
方法返回三個值,分別對應(yīng)三種動作:返回1,則繼續(xù)遞進,把新結(jié)點與下一層的結(jié)點進行比較;
返回0,則該屬性值不足以決定兩結(jié)點位置區(qū)別,再定義其他屬性的比較算法來進一步比較兩對象;
返回-1,則新結(jié)點優(yōu)先級大于當(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ù)組存放對象,用比較器改變sort()排序方法。
數(shù)組本身有默認(rèn)的排序方法,針對int、string等基本類型有默認(rèn)的sort()方法。而針對類對象的排序,可以給sort()方法傳進一個比較器對象,賦予其排序的算法。
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());//傳進來一個比較器對象,使數(shù)組按比較器定義的規(guī)則來排序
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>{//定義比較器
/*
重寫比較方法compare(o1,o2):
方法傳進來兩個對象,用兩個對象的某屬性進行對比,返回一個int。
int>0,則o1排在o2后面;
int<0,則o1排在o2前面;
int=0,則維持原相對位置,即原來存放時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存放對象們,調(diào)用Collections.sort(list,comparator)方法進行排序。
public class CollectionsTest {
public static void main(String[] args) {
Vector<Person> people=new Vector<>();//用向量保存對象
//ArrayList<Person> people=new ArrayList<>()://用ArrayList保存對象。
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)用方法進行排序
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>{//實現(xiàn)Comparator接口,自定義比較器,實現(xiàn)compare方法定義比較算法
/*
compare(o1,o2):方法傳進兩個對象,根據(jù)某屬性進行比較,返回一個int值。
int>0,o1排在o2后;
int<0,o1排在o2前;
int=0,維持原來存放時的相對位置。
*/
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;
}
}
更多關(guān)于java相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Java面向?qū)ο蟪绦蛟O(shè)計入門與進階教程》、《Java數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Java操作DOM節(jié)點技巧總結(jié)》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總》
希望本文所述對大家java程序設(shè)計有所幫助。
相關(guān)文章
springmvc開啟異步請求報錯Java code using the Ser
這篇文章主要為大家介紹了springmvc開啟異步請求報錯Java code using the Servlet API or解決分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2024-02-02
SpringCloud-Spring?Boot?Starter使用測試及問題小結(jié)
Spring?Boot?Starter?是在?SpringBoot?組件中被提出來的一種概念、簡化了很多煩瑣的配置、通過引入各種?Spring?Boot?Starter?包可以快速搭建出一個項目的腳手架,這篇文章主要介紹了SpringCloud-Spring?Boot?Starter使用測試,需要的朋友可以參考下2022-07-07
SpringBoot 接口開發(fā)教程(httpclient客戶端)
這篇文章主要介紹了SpringBoot 接口開發(fā)教程(httpclient客戶端),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03
Java動態(tài)循環(huán)隊列是如何實現(xiàn)的
今天帶大家學(xué)習(xí)java隊列的相關(guān)知識,文章圍繞著如何實現(xiàn)Java動態(tài)循環(huán)隊列展開,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下2021-06-06
SpringBoot + thymeleaf 實現(xiàn)讀取視頻列表并播放視頻功能
這篇文章主要介紹了SpringBoot + thymeleaf 實現(xiàn)讀取視頻列表并播放視頻功能,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-04-04

