上篇讲到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 都提供了工厂方法 。