`
jubin2002
  • 浏览: 39526 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

带你领略 Google Collections

阅读更多

    Java的集合框架是Java类库当中使用频率最高的部分之一,Google公司发起了一个项目,用来扩展Java的集合框架,提供一些高级的集合操作API。

http://code.google.com/p/google-collections/

这个项目叫做Google Collection,托管在Google Code上面,它必须使用JDK5.0以上的版本

 

下面,让我带你领略下这个项目的优雅之处吧

 

1,Immutable Collections

 

什么是Immutable?

 

    Immutable是不可改变的意思。

 

    在JDK中有Collections.unmodifiableFoo()来转换,不过他们之间依然有区别。Collections.unmodifiableFoo()只是原集合的一个视图,在这个视图层面无法修改,但当原集合发生改变时,他也会跟着改变。而ImmutableFoo则是在任何情况下均无法修改。

 

Immutable有什么作用呢?

 

    他们更加容易使用并且安全不易出错。(更多原因请参看Effective JAVA第二版15条)

 

Immutable vs. unmodifiable

 

    虽然JDK的unmodifiable方法也能保证集合视图的不变性。但是Immutable能“保证不可改变”,“极易使用”,“更快”,“使用更少的内存(比如ImmutableSet能少2-3X)”。

 

来看例子程序,以前:

public static final Set<Integer> LUCKY_NUMBERS = 
        Collections.unmodifiableSet(new LinkedHashSet<Integer>(Arrays.asList(4, 8, 15, 16, 23, 42)));

现在:

public static final ImmutableSet<Integer> LUCKY_NUMBERS = 
        ImmutableSet.of(4, 8, 15, 16, 23, 42);

Map 也一样,以前:

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);
}

 现在:

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,以前:

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);
        }
}

 现在:

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

int count(Object element);

int add(E element, int occurrences);// occurrences是指element出现的次数

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

 

以前:

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);
}

 现在:

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:

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:

public Sale getBiggestSale() {
      return Collections.max(multimap.values(),
            SALE_CHARGE_COMPARATOR);
}
 

Multimap有6个有用的方法,get(),keys(), keySet(), values(), entries(), asMap()。

 

大多数Map的方法和Multimaps是一样的,比如说,size(), isEmpty(),containsKey(), containsValue()
put(), putAll(),clear(),values()

 

有些有点区别,比如说,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能互相转换,bimap.inverse().inverse() == bimap

 

BiMap implementations:ImmutableBiMap,HashBiMap,EnumBiMap

 

以前:

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);
  }

 现在:

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);
  }

 更好的:

private static final BiMap<Integer,String> NUMBER_TO_NAME_BIMAP
    = new ImmutableBiMapBuilder<Integer,String>()
        .put(1, "Hydrogen")
        .put(2, "Helium")
        .put(3, "Lithium")
        .getBiMap();
7
0
分享到:
评论
1 楼 sunofsummer 2010-12-29  
google Collections框架真的好强大。

相关推荐

    google-collections-1.0.rar

    google公共工具类;google collections是google的工程师利用传说中的“20%时间”开发的集合库,它是对java.util的扩展,提供了很多实用的类来简化代码。google collections使用了范型,所以要求jdk1.5以上。

    google-collections-1.0-rc2.jar

    google-collections-1.0-rc2.jar 的jar包,放心使用。

    google-collections-1.0-sources.jar

    google-collections-1.0-sources.jar

    Google Collections包

    Java的集合框架是Java类库当中使用频率最高的部分之一,而Google Collections库是由Google基于Java5.0 Collections Framework开发的一套新的Java集合框架,提供一些高级集合操作的API。

    google-collections

    oogle collections是google的工程师利用传说中的“20%时间”开发的集合库,它是对java.util的扩展,提供了很多实用的类来简化代码。google collections使用了范型,所以要求jdk1.5以上。它的作者没有像apache ...

    commons-collections.jar

    commons-collections-20040616.jar, commons-collections-3.2-osgi.jar, commons-collections-3.2-sources.jar, commons-collections-3.2.1.jar, commons-collections-3.2.2-javadoc.jar, commons-collections-3.2.2...

    google-collections-1.0-rc1.jar

    google-collections-1.0-rc1.jar

    google-collections jar包

    import com.google.common.collect.Maps 所需要的jar包

    Google Collections 源代码和API文档

    Google Collections是Google公司开发的常用工具库,包括对字符串,文件操作,数据结构和并发程序开发的支持。它比Apache Commons Collections提供了更多更强大的函数,使得程序编写更加简洁,不易产生错误。 这个...

    commons-collections-3.2.2-API文档-中文版.zip

    赠送jar包:commons-collections-3.2.2.jar; 赠送原API文档:commons-collections-3.2.2-javadoc.jar; 赠送源代码:commons-collections-3.2.2-sources.jar; 赠送Maven依赖信息文件:commons-collections-3.2.2....

    commons-collections4-4.1-API文档-中文版.zip

    赠送jar包:commons-collections4-4.1.jar; 赠送原API文档:commons-collections4-4.1-javadoc.jar; 赠送源代码:commons-collections4-4.1-sources.jar; 赠送Maven依赖信息文件:commons-collections4-4.1.pom;...

    collections-generic-4.01_and_looks-2.1.4

    该文件里包含两个.jar包: collections-generic-4.01.jar和looks-2.1.4.jar, 引入collections-generic-4.01.jar: 右击工程--》Build path ——》Add External JAR--&gt;选中collections-generic-4.01.jar --》OK 在源...

    Google-Guava-Collections-使用介绍

    Collections

    Collections 中部分方法详解如GridView中Collections.swap

    commons-collections4-4.4-API文档-中英对照版.zip

    赠送jar包:commons-collections4-4.4.jar; 赠送原API文档:commons-collections4-4.4-javadoc.jar; 赠送源代码:commons-collections4-4.4-sources.jar; 赠送Maven依赖信息文件:commons-collections4-4.4.pom;...

    commons-collections4-4.4-API文档-中文版.zip

    赠送jar包:commons-collections4-4.4.jar; 赠送原API文档:commons-collections4-4.4-javadoc.jar; 赠送源代码:commons-collections4-4.4-sources.jar; 赠送Maven依赖信息文件:commons-collections4-4.4.pom;...

    google-collections-1.0.jar

    google-collections-1.0.jar

    commons-collections-3.2.2-API文档-中英对照版.zip

    赠送jar包:commons-collections-3.2.2.jar; 赠送原API文档:commons-collections-3.2.2-javadoc.jar; 赠送源代码:commons-collections-3.2.2-sources.jar; 赠送Maven依赖信息文件:commons-collections-3.2.2....

    collections4/collections15 jar

    在Java代码运行时报ClassNotDef 缺少包为collcetions4 或者collections15

    commons-collections-3.2.1-bin

    commons-collections-3.2.1-bin

Global site tag (gtag.js) - Google Analytics