上篇讲到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);
- }
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);
- }
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());
- }
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));
- }
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;
- }
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);
- }
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 ;
- }
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 ;
- }
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();
- }
- }
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);
- }
- }
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>();
Map<CustomerId, BillingOrderHistory> customerOrderHistoryMap
= new HashMap<CustomerId, BillingOrderHistory>();
After:
- Map<CustomerId, BillingOrderHistory> customerOrderHistoryMap
- = Maps.newHashMap();
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" );
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" ));
Set<String> workdays = new LinkedHashSet<String>(
Arrays.asList("Monday", "Tuesday", "Wednesday", "Thursday", "Friday"));
After:
- Set<String> workdays = Sets.newLinkedHashSet(
- "Monday" , "Tuesday" , "Wednesday" , "Thursday" , "Friday" );
Set<String> workdays = Sets.newLinkedHashSet(
"Monday", "Tuesday", "Wednesday", "Thursday", "Friday");
Google Collections 对于Maps, Sets, Lists, Multimaps, Multisets 都提供了工厂方法 。