带你领略 Google Collections 2

上篇讲到google collections的几个比较主要的点,今天我们来看看其提供的几个小的但是相当有用的东西。

 

1,Preconditions

 

Preconditions 提供了状态校验的方法。

 

Before:

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:

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:

public void testWorkSchedule() {
    workSchedule.scheduleUserOnDuty(jesse, mondayAt430pm, mondayAt1130pm);

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

 After:

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:

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:

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:

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:

public boolean orderContains(Product product) {
    for (LineItem lineItem : Iterables.concat(getPurchasedItems(), getFreeItems())) {
      if (lineItem.getProduct() == product) {
        return true;
      }
    }

    return false;
}

 

5,Join

 

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

 

Before:

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:

public class ShoppingList {
  private List<Item> items = ...;

  ...

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

 

6,Maps, Sets and Lists

 

泛型是好的,不过他们有些过于罗嗦。

 

Before:

Map<CustomerId, BillingOrderHistory> customerOrderHistoryMap 
    = new HashMap<CustomerId, BillingOrderHistory>();

 After:

Map<CustomerId, BillingOrderHistory> customerOrderHistoryMap 
    = Maps.newHashMap();

 

Maps, Sets and Lists 包含了工厂方法来创建集合对象。

 

另一个例子,Before:

Set<String> workdays = new LinkedHashSet<String>();
workdays.add("Monday");
workdays.add("Tuesday");
workdays.add("Wednesday");
workdays.add("Thursday");
workdays.add("Friday");

 OR:

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

 After:

Set<String> workdays = Sets.newLinkedHashSet(
  "Monday", "Tuesday", "Wednesday", "Thursday", "Friday");

 

Google Collections 对于Maps, Sets, Lists, Multimaps, Multisets 都提供了工厂方法 。

你可能感兴趣的:(Google,单元测试)