国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
帶你領略 Google Collections
userphoto

2010.11.24

關注
Java的集合框架是Java類庫當中使用頻率最高的部分之一,Google公司發(fā)起了一個項目,用來擴展Java的集合框架,提供一些高級的集合操作API。
http://code.google.com/p/google-collections/
這個項目叫做Google Collection,托管在Google Code上面,它必須使用JDK5.0以上的版本
下面,讓我?guī)泐I略下這個項目的優(yōu)雅之處吧
1,Immutable Collections
什么是Immutable?
Immutable是不可改變的意思。
在JDK中有Collections.unmodifiableFoo()來轉(zhuǎn)換,不過他們之間依然有區(qū)別。Collections.unmodifiableFoo()只是原集合的一個視圖,在這個視圖層面無法修改,但當原集合發(fā)生改變時,他也會跟著改變。而ImmutableFoo則是在任何情況下均無法修改。
Immutable有什么作用呢?
他們更加容易使用并且安全不易出錯。(更多原因請參看Effective JAVA第二版15條)
Immutable vs. unmodifiable
雖然JDK的unmodifiable方法也能保證集合視圖的不變性。但是Immutable能“保證不可改變”,“極易使用”,“更快”,“使用更少的內(nèi)存(比如ImmutableSet能少2-3X)”。
來看例子程序,以前:
Java代碼 
public static final Set<Integer> LUCKY_NUMBERS =            Collections.unmodifiableSet(new LinkedHashSet<Integer>(Arrays.asList(4, 8, 15, 16, 23, 42)));
現(xiàn)在:
Java代碼 
public static final ImmutableSet<Integer> LUCKY_NUMBERS =            ImmutableSet.of(4, 8, 15, 16, 23, 42);
Map 也一樣,以前:
Java代碼 
public static final Map<String, Integer> ENGLISH_TO_INT;      static {           Map<String, Integer> map = new LinkedHashMap<String, Integer>();           map.put("four", 4);           map.put("eight", 8);           map.put("fifteen", 15);           map.put("sixteen", 16);            map.put("twenty-three", 23);           map.put("forty-two", 42);           ENGLISH_TO_INT = Collections.unmodifiableMap(map);   }
現(xiàn)在:
Java代碼 
ImmutableMap<String, Integer> map =            ImmutableMap.of("four", 4,"eight", 8, "fifteen", 15, "sixteen", 16, "twenty-three", 23,"forty-two", 42);
在google,In the past, we'd ask, "does this need to be immutable?"
Now we ask, "does it need to be mutable?"
2,Multisets
什么是Multisets?
當我們有一捆東西的時候我們就會想到用集合,但是我們要用什么樣的集合呢,在這,我們會考慮以下幾點
1)他能重復么,2)他的排序有意義么,3)他的插入順序
List:有序,可以重復,Set:無序,不可以重復
而MultiSets是無序,可以重復的
請看例子,tag,以前:
Java代碼 
Map<String, Integer> tags           = new HashMap<String, Integer>();      for (BlogPost post : getAllBlogPosts()) {           for (String tag : post.getTags()) {                   int value = tags.containsKey(tag) ? tags.get(tag) : 0;                   tags.put(tag, value + 1);           }   }
現(xiàn)在:
Java代碼 
Multiset<String> tags = HashMultiset.create();           for (BlogPost post : getAllBlogPosts()) {           tags.addAll(post.getTags());           System.out.println(tags.toString()); //輸出[sasa, yaomin x 2, jubin x 2, lele]   }
Multiset API
Java代碼 
int count(Object element);      int add(E element, int occurrences);// occurrences是指element出現(xiàn)的次數(shù)      boolean remove(Object element, int occurrences);      int setCount(E element, int newCount);      boolean setCount(E e, int oldCount, int newCount);
Multiset implementations:
ImmutableMultiset,HashMultiset,LinkedHashMultiset,TreeMultiset,EnumMultiset,ConcurrentMultiset
3,Multimaps
以前:
Java代碼 
Map<Salesperson, List<Sale>> map         = new HashMap<Salesperson, List<Sale>>();      public void makeSale(Salesperson salesPerson, Sale sale) {         List<Sale> sales = map.get(salesPerson);         if (sales == null) {               sales = new ArrayList<Sale>();               map.put(salesPerson, sales);         }         sales.add(sale);   }
現(xiàn)在:
Java代碼 
Multimap<Salesperson, Sale> multimap         = ArrayListMultimap.create();      public void makeSale(Salesperson salesPerson, Sale sale) {         multimap.put(salesPerson, sale);   }
什么是Multimaps?
類似Map的一種以key-value是對的集合,不過他的key不需要唯一。{a=1, a=2, b=3, c=4, c=5, c=6}
multimap.get(key)會返回一個可修改的集合視圖,或者你也可以把它看做Map<K, Collection<V>>
{a=[1, 2], b=[3], c=[4, 5, 6]}
再看一個例子,在上個例子的基礎上找到最大的sale,沒用Multimaps:
Java代碼 
public Sale getBiggestSale() {         Sale biggestSale = null;         for (List<Sale> sales : map.values()) {               Sale myBiggestSale = Collections.max(sales,                     SALE_CHARGE_COMPARATOR);               if (biggestSale == null ||                     myBiggestSale.getCharge() > biggestSale().getCharge()) {                     biggestSale = myBiggestSale;               }         }         return biggestSale;   }
用了Multimaps:
Java代碼 
public Sale getBiggestSale() {         return Collections.max(multimap.values(),               SALE_CHARGE_COMPARATOR);   }
Multimap有6個有用的方法,get(),keys(), keySet(), values(), entries(), asMap()。
大多數(shù)Map的方法和Multimaps是一樣的,比如說,size(), isEmpty(),containsKey(), containsValue()
put(), putAll(),clear(),values()
有些有點區(qū)別,比如說,get()返回Collection<V>而不是V,remove(K)變成remove(K,V)和removeAll(K),keySet()變成keys(),entrySet()變成entries()
Multimap implementations:ImmutableMultimap,ArrayListMultimap,HashMultimap
LinkedHashMultimap,TreeMultimap
3,BiMap
BiMap又名unique-valued map,也就是說,他的key和value都是不能重復的,這就導致了他的key和value能互相轉(zhuǎn)換,bimap.inverse().inverse() == bimap
BiMap implementations:ImmutableBiMap,HashBiMap,EnumBiMap
以前:
Java代碼 
private static final Map<Integer, String> NUMBER_TO_NAME;     private static final Map<String, Integer> NAME_TO_NUMBER;          static {       NUMBER_TO_NAME = Maps.newHashMap();       NUMBER_TO_NAME.put(1, "Hydrogen");       NUMBER_TO_NAME.put(2, "Helium");       NUMBER_TO_NAME.put(3, "Lithium");              /* reverse the map programatically so the actual mapping is not repeated */       NAME_TO_NUMBER = Maps.newHashMap();       for (Integer number : NUMBER_TO_NAME.keySet()) {         NAME_TO_NUMBER.put(NUMBER_TO_NAME.get(number), number);       }     }        public static int getElementNumber(String elementName) {       return NUMBER_TO_NAME.get(elementName);     }        public static string getElementName(int elementNumber) {       return NAME_TO_NUMBER.get(elementNumber);     }
現(xiàn)在:
Java代碼 
private static final BiMap<Integer,String> NUMBER_TO_NAME_BIMAP;          static {       NUMBER_TO_NAME_BIMAP = Maps.newHashBiMap();       NUMBER_TO_NAME_BIMAP.put(1, "Hydrogen");       NUMBER_TO_NAME_BIMAP.put(2, "Helium");       NUMBER_TO_NAME_BIMAP.put(3, "Lithium");     }        public static int getElementNumber(String elementName) {       return NUMBER_TO_NAME_BIMAP.inverse().get(elementName);     }        public static string getElementName(int elementNumber) {       return NUMBER_TO_NAME_BIMAP.get(elementNumber);     }
更好的:
Java代碼 
private static final BiMap<Integer,String> NUMBER_TO_NAME_BIMAP       = new ImmutableBiMapBuilder<Integer,String>()           .put(1, "Hydrogen")           .put(2, "Helium")           .put(3, "Lithium")           .getBiMap();
上篇講到google collections的幾個比較主要的點,今天我們來看看其提供的幾個小的但是相當有用的東西。
1,Preconditions
Preconditions 提供了狀態(tài)校驗的方法。
Before:
Java代碼 
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代碼 
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代碼 
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代碼 
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...)提供了內(nèi)建的null處理,能使你實現(xiàn)equals()和hashCode()更加簡單。
Before:
Java代碼 
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代碼 
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() 連結(jié)多種集合 (比如ArrayList和HashSet) 以至于你能在一行代碼里遍歷他們:
Before:
Java代碼 
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代碼 
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代碼 
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代碼 
public class ShoppingList {     private List<Item> items = ...;        ...        public String toString() {       return Joiner.on(" and ").join(items);     }   }
6,Maps, Sets and Lists
泛型是好的,不過他們有些過于羅嗦。
Before:
Java代碼 
Map<CustomerId, BillingOrderHistory> customerOrderHistoryMap        = new HashMap<CustomerId, BillingOrderHistory>();
After:
Java代碼 
Map<CustomerId, BillingOrderHistory> customerOrderHistoryMap        = Maps.newHashMap();
Maps, Sets and Lists 包含了工廠方法來創(chuàng)建集合對象。
另一個例子,Before:
Java代碼 
Set<String> workdays = new LinkedHashSet<String>();   workdays.add("Monday");   workdays.add("Tuesday");   workdays.add("Wednesday");   workdays.add("Thursday");   workdays.add("Friday");
OR:
Java代碼 
Set<String> workdays = new LinkedHashSet<String>(     Arrays.asList("Monday", "Tuesday", "Wednesday", "Thursday", "Friday"));
After:
Java代碼 
Set<String> workdays = Sets.newLinkedHashSet(     "Monday", "Tuesday", "Wednesday", "Thursday", "Friday");
Google Collections 對于Maps, Sets, Lists, Multimaps, Multisets 都提供了工廠方法 。
本站僅提供存儲服務,所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Google Guava Collections 使用介紹
google collection
map的三種遍歷方法
Java Iterator(迭代器) | 菜鳥教程
8.4 JSON轉(zhuǎn)換器 - 接口實現(xiàn) - AJava
多角度看 Java 中的泛型
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服