帶你領略 Google Collections 2

原貼地址:

http://jubin2002.javaeye.com/blog/471698

 

上篇講到google collections的幾個比較主要的點,今天我們來看看其提供的幾個小的但是相當有用的東西。

 

1,Preconditions

 

Preconditions 提供了狀態校驗的方法。

 

Before:

Java代碼
  1. public  Delivery createDelivery(Order order, User deliveryPerson) {  
  2.       
  3.     if (order.getAddress() ==  null ) {  
  4.         throw   new  NullPointerException( "order address" );  
  5.     }  
  6.       
  7.     if (!workSchedule.isOnDuty(deliveryPerson, order.getArrivalTime())) {  
  8.         throw   new  IllegalArgumentException(  
  9.             String.format("%s is not on duty for %s" , deliveryPerson, order));  
  10.     }  
  11.   
  12.     return   new  RealDelivery(order, deliveryPerson);  
  13. }  
public Delivery createDelivery(Order order, User deliveryPerson) {
    
    if(order.getAddress() == null) {
        throw new NullPointerException("order address");
    }
    
    if(!workSchedule.isOnDuty(deliveryPerson, order.getArrivalTime())) {
        throw new IllegalArgumentException(
            String.format("%s is not on duty for %s", deliveryPerson, order));
    }

    return new RealDelivery(order, deliveryPerson);
}

 After:

Java代碼
  1. public  Delivery createDelivery(Order order, User deliveryPerson) {  
  2.     Preconditions.checkNotNull(order.getAddress(), "order address" );  
  3.     Preconditions.checkArgument(  
  4.         workSchedule.isOnDuty(deliveryPerson, order.getArrivalTime()),  
  5.             "%s is not on duty for %s" , deliveryPerson, order);  
  6.   
  7.     return   new  RealDelivery(order, deliveryPerson);  
  8. }  
public Delivery createDelivery(Order order, User deliveryPerson) {
    Preconditions.checkNotNull(order.getAddress(), "order address");
    Preconditions.checkArgument(
        workSchedule.isOnDuty(deliveryPerson, order.getArrivalTime()),
            "%s is not on duty for %s", deliveryPerson, order);

    return new RealDelivery(order, deliveryPerson);
}
 

2,Iterables.getOnlyElement

 

Iterables.getOnlyElement 確保你的集合或者迭代器包含了剛好一個元素並且返回該元素。如果他包含0和2+元素,它會拋出RuntimeException。一般在單元測試中使用。

 

Before:

Java代碼
  1. public   void  testWorkSchedule() {  
  2.     workSchedule.scheduleUserOnDuty(jesse, mondayAt430pm, mondayAt1130pm);  
  3.   
  4.     Set<User> usersOnDuty = workSchedule.getUsersOnDuty(mondayAt800pm);  
  5.     assertEquals(1 , usersOnDuty.size());  
  6.     assertEquals(jesse, usersOnDuty.iterator().next());  
  7. }  
public void testWorkSchedule() {
    workSchedule.scheduleUserOnDuty(jesse, mondayAt430pm, mondayAt1130pm);

    Set<User> usersOnDuty = workSchedule.getUsersOnDuty(mondayAt800pm);
    assertEquals(1, usersOnDuty.size());
    assertEquals(jesse, usersOnDuty.iterator().next());
}

 After:

Java代碼
  1. public   void  testWorkSchedule() {  
  2.     workSchedule.scheduleUserOnDuty(jesse, mondayAt430pm, mondayAt1130pm);  
  3.   
  4.     Set<User> usersOnDuty = workSchedule.getUsersOnDuty(mondayAt800pm);  
  5.     assertEquals(jesse, Iterables.getOnlyElement(usersOnDuty));  
  6. }  
public void testWorkSchedule() {
    workSchedule.scheduleUserOnDuty(jesse, mondayAt430pm, mondayAt1130pm);

    Set<User> usersOnDuty = workSchedule.getUsersOnDuty(mondayAt800pm);
    assertEquals(jesse, Iterables.getOnlyElement(usersOnDuty));
}

 Iterables.getOnlyElement比Set.iterator().getNext()和List.get(0)描述的更爲直接。


3,Objects.equal

 

Objects.equal(Object,Object) and Objects.hashCode(Object...)提供了內建的null處理,能使你實現equals()hashCode()更加簡單。

 

Before:

Java代碼
  1. public   boolean  equals(Object o) {  
  2.     if  (o  instanceof  Order) {  
  3.       Order that = (Order)o;  
  4.   
  5.       return  (address !=  null    
  6.               ? address.equals(that.address)   
  7.               : that.address == null )   
  8.           && (targetArrivalDate != null    
  9.               ? targetArrivalDate.equals(that.targetArrivalDate)   
  10.               : that.targetArrivalDate == null )  
  11.           && lineItems.equals(that.lineItems);  
  12.     } else  {  
  13.       return   false ;  
  14.     }  
  15. }  
  16.   
  17. public   int  hashCode() {  
  18.     int  result =  0 ;  
  19.     result = 31  * result + (address !=  null  ? address.hashCode() :  0 );  
  20.     result = 31  * result + (targetArrivalDate !=  null  ? targetArrivalDate.hashCode() :  0 );  
  21.     result = 31  * result + lineItems.hashCode();  
  22.     return  result;  
  23. }  
public boolean equals(Object o) {
    if (o instanceof Order) {
      Order that = (Order)o;

      return (address != null 
              ? address.equals(that.address) 
              : that.address == null) 
          && (targetArrivalDate != null 
              ? targetArrivalDate.equals(that.targetArrivalDate) 
              : that.targetArrivalDate == null)
          && lineItems.equals(that.lineItems);
    } else {
      return false;
    }
}

public int hashCode() {
    int result = 0;
    result = 31 * result + (address != null ? address.hashCode() : 0);
    result = 31 * result + (targetArrivalDate != null ? targetArrivalDate.hashCode() : 0);
    result = 31 * result + lineItems.hashCode();
    return result;
}

 After:

Java代碼
  1. public   boolean  equals(Object o) {  
  2.     if  (o  instanceof  Order) {  
  3.       Order that = (Order)o;  
  4.   
  5.       return  Objects.equal(address, that.address)  
  6.           && Objects.equal(targetArrivalDate, that.targetArrivalDate)  
  7.           && Objects.equal(lineItems, that.lineItems);  
  8.     } else  {  
  9.       return   false ;  
  10.     }  
  11. }  
  12.   
  13. public   int  hashCode() {  
  14.     return  Objects.hashCode(address, targetArrivalDate, lineItems);  
  15. }  
public boolean equals(Object o) {
    if (o instanceof Order) {
      Order that = (Order)o;

      return Objects.equal(address, that.address)
          && Objects.equal(targetArrivalDate, that.targetArrivalDate)
          && Objects.equal(lineItems, that.lineItems);
    } else {
      return false;
    }
}

public int hashCode() {
    return Objects.hashCode(address, targetArrivalDate, lineItems);
}

 

4,Iterables.concat()

 

Iterables.concat() 連結多種集合 (比如ArrayList和HashSet) 以至於你能在一行代碼裏遍歷他們:

 

Before:

Java代碼
  1. public   boolean  orderContains(Product product) {  
  2.     List<LineItem> allLineItems = new  ArrayList<LineItem>();  
  3.     allLineItems.addAll(getPurchasedItems());  
  4.     allLineItems.addAll(getFreeItems());  
  5.   
  6.     for  (LineItem lineItem : allLineItems) {  
  7.       if  (lineItem.getProduct() == product) {  
  8.         return   true ;  
  9.       }  
  10.     }  
  11.   
  12.     return   false ;  
  13. }  
public boolean orderContains(Product product) {
    List<LineItem> allLineItems = new ArrayList<LineItem>();
    allLineItems.addAll(getPurchasedItems());
    allLineItems.addAll(getFreeItems());

    for (LineItem lineItem : allLineItems) {
      if (lineItem.getProduct() == product) {
        return true;
      }
    }

    return false;
}

 After:

Java代碼
  1. public   boolean  orderContains(Product product) {  
  2.     for  (LineItem lineItem : Iterables.concat(getPurchasedItems(), getFreeItems())) {  
  3.       if  (lineItem.getProduct() == product) {  
  4.         return   true ;  
  5.       }  
  6.     }  
  7.   
  8.     return   false ;  
  9. }  
public boolean orderContains(Product product) {
    for (LineItem lineItem : Iterables.concat(getPurchasedItems(), getFreeItems())) {
      if (lineItem.getProduct() == product) {
        return true;
      }
    }

    return false;
}

 

5,Join

 

Join 是用分隔符分割字符串變得非常容易。

 

Before:

Java代碼
  1. public   class  ShoppingList {  
  2.   private  List<Item> items = ...;  
  3.   
  4.   ...  
  5.   
  6.   public  String toString() {  
  7.     StringBuilder stringBuilder = new  StringBuilder();  
  8.     for  (Iterator<Item> s = items.iterator(); s.hasNext(); ) {  
  9.       stringBuilder.append(s.next());  
  10.       if  (s.hasNext()) {  
  11.         stringBuilder.append(" and " );  
  12.       }  
  13.     }  
  14.     return  stringBuilder.toString();  
  15.   }  
  16. }  
public class ShoppingList {
  private List<Item> items = ...;

  ...

  public String toString() {
    StringBuilder stringBuilder = new StringBuilder();
    for (Iterator<Item> s = items.iterator(); s.hasNext(); ) {
      stringBuilder.append(s.next());
      if (s.hasNext()) {
        stringBuilder.append(" and ");
      }
    }
    return stringBuilder.toString();
  }
}
 

After:

Java代碼
  1. public   class  ShoppingList {  
  2.   private  List<Item> items = ...;  
  3.   
  4.   ...  
  5.   
  6.   public  String toString() {  
  7.     return  Joiner.on( " and " ).join(items);  
  8.   }  
  9. }  
public class ShoppingList {
  private List<Item> items = ...;

  ...

  public String toString() {
    return Joiner.on(" and ").join(items);
  }
}

 

6,Maps, Sets and Lists

 

泛型是好的,不過他們有些過於羅嗦。

 

Before:

Java代碼
  1. Map<CustomerId, BillingOrderHistory> customerOrderHistoryMap   
  2.     = new  HashMap<CustomerId, BillingOrderHistory>();  
Map<CustomerId, BillingOrderHistory> customerOrderHistoryMap 
    = new HashMap<CustomerId, BillingOrderHistory>();

 After:

Java代碼
  1. Map<CustomerId, BillingOrderHistory> customerOrderHistoryMap   
  2.     = Maps.newHashMap();  
Map<CustomerId, BillingOrderHistory> customerOrderHistoryMap 
    = Maps.newHashMap();

 

Maps, Sets and Lists 包含了工廠方法來創建集合對象。

 

另一個例子,Before:

Java代碼
  1. Set<String> workdays =  new  LinkedHashSet<String>();  
  2. workdays.add("Monday" );  
  3. workdays.add("Tuesday" );  
  4. workdays.add("Wednesday" );  
  5. workdays.add("Thursday" );  
  6. workdays.add("Friday" );  
Set<String> workdays = new LinkedHashSet<String>();
workdays.add("Monday");
workdays.add("Tuesday");
workdays.add("Wednesday");
workdays.add("Thursday");
workdays.add("Friday");

 OR:

Java代碼
  1. Set<String> workdays =  new  LinkedHashSet<String>(  
  2.   Arrays.asList("Monday" "Tuesday" "Wednesday" "Thursday" "Friday" ));  
Set<String> workdays = new LinkedHashSet<String>(
  Arrays.asList("Monday", "Tuesday", "Wednesday", "Thursday", "Friday"));

 After:

Java代碼
  1. Set<String> workdays = Sets.newLinkedHashSet(  
  2.   "Monday" "Tuesday" "Wednesday" "Thursday" "Friday" );  
Set<String> workdays = Sets.newLinkedHashSet(
  "Monday", "Tuesday", "Wednesday", "Thursday", "Friday");

 

Google Collections 對於Maps, Sets, Lists, Multimaps, Multisets 都提供了工廠方法 。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章