1. 程式人生 > 程式設計 >Java實現儲存物件並按物件某屬性排序的幾種方法示例

Java實現儲存物件並按物件某屬性排序的幾種方法示例

本文例項講述了Java實現儲存物件並按物件某屬性排序的幾種方法。分享給大家供大家參考,具體如下:

在程式設計的時候,經常會出現對某一種類的物件們按照某屬性進行自定義的排序,比如:學生物件按照age大小排序。

有一種方法就是把age單獨提出來排好序,然後按照ages陣列的順序把students重存一次。但是這樣太繁瑣了,有沒有更好的方法呢?

有滴~

第一種,可以實現邊新增邊排序,需要用到TreeSet。

第二種,用陣列存放物件們,但是不需單獨取出某屬性排列好再重存,而是在原陣列上用比較器重新排一次序。需要用到Arrays.sort(arr,comparator)。

第三種,用集合類中的list的子類存放物件們,然後排序。需要用到Collections.sort(list,comparator)。

以下分別討論:

一、TreeSet

建立:

序號 建構函式的說明
1 TreeSet ()

此建構函式構造空樹集,將在根據其元素的自然順序按升序排序。

2 TreeSet (集合 c)

此建構函式生成樹的集合,它包含的元素的集合 c。

3 TreeSet (比較器 comp)

此建構函式構造一個空樹集,將根據給定的比較器進行排序。

增:

boolean add(Ee) 將指定的元素新增到這套,如果它已不存在。
boolean addAll(Collection<? extendsE>c) 在加入這一組指定的集合中新增的所有元素。

刪:

boolean remove(Objecto) 從這一組中移除指定的元素,如果它存在。
void clear() 從這一組中移除所有元素。

查:

Comparator<? superE> comparator() 返回用於排序在這集,或元素,如果這套使用自然排序其元素的比較。
boolean contains(Objecto) 如果此集合包含指定的元素,則返回true
boolean isEmpty() 如果此集不包含任何元素,則返回true
Iterator<E> iterator() 返回迭代器中這套以升序排序的元素。
int size() 在這套 (其基數) 中返回的元素的數目。

遍歷:通過迭代器遍歷。

Iterator it=treeset.iterator();
while(it.hasNext()){
 //操作當前結點。
}

程式碼實現:

TreeSet是一個有序集合,TreeSet中的元素將按照升序排列。

TreeSet儲存物件的時候,可以排序,其中Integer有預設排序方法,String有預設排序方法,,而自定義的類物件儲存的時候則沒有順序,需要自定義排序演算法。

如果想把自定義類的物件存入TreeSet進行排序,或者對int,String物件想定義自己的排序方法,有以下兩種方法:

排序的第一種方式:

讓元素自身具備比較性。讓元素實現Comparable介面,覆蓋compareTo方法,在方法內定義比較演算法,根據大小關係,返回正數負數或零。在使用TreeSet儲存物件的時候,add()方法內部就會自動呼叫compareTo()方法進行比較,根據比較結果使用二叉樹形式進行儲存。

排序的第二種方式:

   自定義比較器。定義一個類實現Comparator介面,覆蓋compare方法。將該Comparator介面子類物件傳遞給TreeSet集合建構函式。

第一種:類定義時實現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{  //定義類時,實現比較介面

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):引數是從根節點開始依次傳進來的結點,直到確定合適的位置用來安插新節點。
方法返回三個值,分別對應三種動作:返回1,則繼續遞進,把新結點與下一層的結點進行比較;
返回0,則該屬性值不足以決定兩結點位置區別,再定義其他屬性的比較演算法來進一步比較兩物件;
返回-1,則新結點優先順序大於當前層,往上一層比較;
*/
public int compareTo(Object o) {
Person curr=(Person) o;
//int result = this.age<curr.age?1:(this.age==curr.age?0:-1);//降序排列:新插入結點與當前比較層結點的屬性比較,小則返回1,繼續往下一層比較
int result = this.age>curr.age?1:(this.age==curr.age?0:-1);//升序排列:新插入結點與當前比較層結點的屬性比較,大則返回1,繼續往下一層比較
if(result==0){
result=this.name.compareTo(curr.name);//age相同時,則以姓名的字母序來排列。前面說過,int、string型別是有預設排列演算法的,所以此處直接用 
}
return result;
} 
}

 

第二種:定義Comparator介面的實現類(比較器),在類中定義物件的比較演算法。在建立Treeset時把比較器物件傳進去。

public class TreeSetTest {

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
TreeSet people=new TreeSet(new MyComparator());//把比較器物件作為TreeSet的建構函式引數
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,年齡:"+age;
}

}
class MyComparator implements Comparator{//實現Comparator介面,自定義比較器,實現compare方法定義比較演算法

/*
compare(o1,o2):引數o1是待插入的結點,o2是從樹根節點逐層遍歷下來的結點,用於當前比較。
方法返回三個值,分別對應三種動作:返回1,則繼續遞進,把新結點與下一層的結點進行比較;
返回0,則該屬性值不足以決定兩結點位置區別,再定義其他屬性的比較演算法來進一步比較兩物件;
返回-1,則新結點優先順序大於當前層,往上一層比較;

*/
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;
}

}

二、用陣列存放物件,用比較器改變sort()排序方法。

陣列本身有預設的排序方法,針對int、string等基本型別有預設的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());//傳進來一個比較器物件,使陣列按比較器定義的規則來排序
for(Person i:people){
System.out.println(i);
}

}

}
class Person {

String name;
int age;

public Person() {
}

public Person(String 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存放物件們,呼叫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("小明",35));
Collections.sort(people,new MyComparator());//呼叫方法進行排序
Iterator it=people.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}

}
class Person {

String name;
int age;

public Person() {
}

public Person(String name,年齡:"+age;
}

}
class MyComparator implements Comparator<Person>{//實現Comparator介面,自定義比較器,實現compare方法定義比較演算法

/*
compare(o1,o2):方法傳進兩個物件,根據某屬性進行比較,返回一個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;
}

}

 

更多關於java相關內容感興趣的讀者可檢視本站專題:《Java面向物件程式設計入門與進階教程》、《Java資料結構與演算法教程》、《Java操作DOM節點技巧總結》、《Java檔案與目錄操作技巧彙總》和《Java快取操作技巧彙總》

希望本文所述對大家java程式設計有所幫助。