1. 程式人生 > >guava之比較器(1)

guava之比較器(1)

對於一個學習java加工作兩年還不到的程式設計師,這個時候接觸一種java類庫的擴充套件似乎不太合適,但是學習東西的新鮮感還是嗖嗖嗖的飛了出來,在網上瀏覽文章時,無意間看到了google的guava專案,覺得有點意思,就搜尋有關guava的學習教程,粗略學習嘗試之後,便感覺對這個類庫已經放不下了,後面會繼續努力學的更深入點。

現在在這裡,主要簡單介紹一個guava裡面強大的“流暢風格比較器”!

排序器——Ordering

ordering實現了java的conparator介面,Ordering把很多基於Comparator的靜態方法(如Collections.max)包裝為自己的例項方法(非靜態方法),並且提供了鏈式呼叫方法,來定製和增強現有的比較器。

怎麼建立排序器呢?或者說我們可以建個怎樣的排序器呢?

一、小例項

1.首先,我們先建立一個實體類User

public class User {
private String username;
private int age;
private String password;
public User() {
}
public User(String username, int age) {
super();
this.username = username;
this.age = age;
}

public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}

2.編寫測試用例

@Test
public void test01(){
User user1 = new User();
user1.setUsername("zhagnsan");
user1.setAge(22);
user1.setPassword("123");
User user2 = new User();
user2.setUsername("aisi");
user2.setAge(2);
user2.setPassword("123");
User user3 = new User();
user3.setUsername("wangwu");
user3.setAge(56);
user3.setPassword("123");
List<User> us = new ArrayList<User>();
us.add(user1);
us.add(user2);
us.add(user3);
//建立ordering例項,並編寫排序規則
Ordering<User> ordering = new Ordering<User>() {
@Override
public int compare(User u1, User u2) {
return Ints.compare(u1.getAge(), u2.getAge());
}
};
Collections.sort(us, ordering);
for (User user : us) {
System.out.println(user.getUsername()+"..."+user.getAge()+"..."+user.getPassword());
}
}
排序結果

通過這個,我們實現了按照年齡排序,實現java原生排序的寫法,接下來我們來看一看其他不一樣的寫法和用法

二、主要方法和用法

1、natural()   對可排序型別做自然排序,如按照數字大小,日期按照先後排序

(1)通過描述我們知道,如果單獨呼叫這個方法,我們首先要保證排序的類是可排序的,這裡用到的實現可排序的,就是java提供的comparable介面,需要我們的User類實現此介面,並實現compareTo方法



中間的程式碼省略
用法:
//呼叫自然排序規則
Ordering<User> ordering = Ordering.natural();
Collections.sort(us, ordering);
//其他程式碼和小例項測試程式碼一樣

結果:

我們可以看到,實現了按照姓名的自然排序,如果覺得這樣寫還是不過癮

那麼我們這些寫,不對User類實現可排序,而在我們呼叫排序方法的時候,實現排序規則

(2)實現按照姓名排序,且名字為null的排在前面(此時User沒有實現comparable介面)

用法:

//呼叫自然排序,自定義排序列,並且為null的排在前面
Ordering<User> ordering = Ordering.natural().nullsFirst().onResultOf(new Function<User, String>() {
@Override
public String apply(User u) {
return u.getUsername();
}
});
Collections.sort(us, ordering);
//其餘程式碼省略,同小案例
結果:
我們可以看到實現了按照名字的自然排序,並且實現了將名字為null的排在前面

這裡簡單講解一下上面的方法:

Function介面:第一個引數是要排序的引數的所在類,第二個引數是要排序的引數的型別,實現apply方法,返回我們要自然排序的引數

NullsFirst():此方法實現了排序引數為null的排在前面的效果

此外還有 NullsLast(),實現null引數排在後面的效果;reverse()方法,實現將排序好的結果反向輸出

注意:

由於guava使用了大量的鏈式程式設計,因此我們可以一路在方法後面點出其他的方法,如上面的reverse()方法,我們可以在natural()方法後面呼叫,也可以在NullsFirst()方法後面呼叫,還可以在OnResultOf()後面呼叫。
但是這裡特別要注意的,這裡的實現使用了裝飾模式,因此每呼叫一個方法,都是對上一個方法呼叫結果的封裝,因此呼叫的順序要注意,否則會得到意想不到的結果甚至報錯
例如上面的例子,如果在OnResultOf()方法後面呼叫NullsFirst()方法,那麼就會報空指標異常
然而,如果是正常且合理的呼叫,則能夠組合出很多效果,這也是這個比較器的強大,
例如:
Ordering<User> ordering = Ordering.natural().reverse().nullsFirst().onResultOf(new Function<User, String>() {
@Override
public String apply(User u) {
return u.getUsername();
}
});
Collections.sort(us, ordering);
//此程式碼就實現了按照名字自然排序,然後將其反序輸出,然後將null值得排在前列
更多的組合使用方法,我們可以自己再去探索
我也就簡單介紹到這,後面的我慢慢介紹,友友們可以自己去搜搜相關文件,嘿嘿。。。。