分享

google collection

 碧海山城 2010-08-27

Google 集合框架

 

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

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

这个项目叫做Google Collection,托管在Google Code上面,它必须使用JDK5.0以上的版本,这是因为Google Collections使用了JDK5.0的泛型语法,它提供了如下的高级集合特性:

1
BiMap,即双向映射,可以从key映射到value,还可以反过来从value映射到key,当然,keyvalue集合元素不能有重复的,BiMap在很多场合很有用处。

2
MultiSet,即多元素集,可以拥有重复元素的无序集合,类似于Hibernate集合映射当中的Bag的概念,填补了Java集合框架缺失的一项。

3
MultiMap,即多集映射,也就是keyMultiSet集合的映射,它还有两个子类SetMultimapListMultimap

这些新的集合接口类都有一大串相应的具体实现类,就不一一介绍了。

集合的工具类添加了如下的内容:

1
Comparators,比较器,支持自然排序,空值
2
Iterators 迭代器,支持元素遍历判等,循环,连接,分钱,过滤等等操作。
3
Lists, SetsMaps 相应集合接口实现类的方便的操作功能。

 

Google Collections 1.0 最终版发布


1.0
新特性:

·         新的集合类型:Multimap, Multiset, BiMap和一些其它的类型;

·         高效的不可变集合类型,例如:ImmutableSet

·         更方便的集合排序功能;

·         新增了一个被称之为MapMaker的类 用于创建带有更多高级特性的并发HashMap

·         新增了针对集合类的迭代器和迭代器工具类,用于方便的实现各种集合类的迭代;

·         新增了很多针对Lists,SetsMaps的工具类;

·         新增了转发集合类,借助转发集合类,可以自定义集合类的特性,而不需要继承其它集合类;

·         新增了针对帮助类的实现,例如:AbstractIterator……

1.  Immutable 不可变的

Goolgle collection中有一堆ImmutableXXX,比如ImmutableListImmutableMap

在标准JDKCollections,有Collections.unmodifiableCollection方法可以返回指定集合的不可修改视图,这个视图无法更改,但是当原集合发生改变时,他也会跟着改变。

 

googleImmutable,则是在任何情况下都无法修改,类似这种对象安全,不易出错。虽然JDKunmodifiable方法也能保证集合视图的不变性。但是Immutable能“保证不可改变”,“极易使用”,“更快”,“使用更少的内存(比如ImmutableSet能少2-3X)”

 

虽然这些类不是final的,但是他们都没有公共的或者受保护的构造方法,所以可以保证不会被修改。ImmutableXXX都需要ImmutableXX.Builder类去创建,这些builder类,可以添加多个相应集合,然后依次性的build

 

List list=new ArrayList();

      list.add("a");

      list.add("b");

      list.add("c");

     

      List list2=new ArrayList();

      list2.add("a");

      list2.add("b");

     

      //以前

      List T_LIST=Collections.unmodifiableList(list);

      Set<Integer> LUCKY_NUMBERS =  

    Collections.unmodifiableSet(new LinkedHashSet<Integer>(

Arrays.asList(4, 8, 15, 16, 23, 42))); 

 

      ImmutableList.Builder ib=new ImmutableList.Builder();

      ib.add(list);

      ImmutableList<String> il=ib.build();

      ListIterator li=il.listIterator();

      while(li.hasNext()){

         System.out.println(li.next());

      }

     

      il=il.of("1234", "3434", "6666");

       li=il.listIterator();

      while(li.hasNext()){

         System.out.println(li.next());

      }

 

       结果:

              [a, b, c]

1234

3434

6666

       SetMap也是类似的。

 

 

2.  Multisets 重复的,允许重复的元素,无序的。

List:有序的,允许重复

Set:无序的,不允许重复

 

HashMultiMap(继承自MultiMap)、HashMultiSet(继承自MultiSet)。Map中看,一个键可以有多个重复的值,所以他的get(K)方法返回一个集合。

 

   Multimap implementationsImmutableMultimapArrayListMultimapHashMultimap

      LinkedHashMultimapTreeMultimap等。

 

原来的代码,在将一个元素加入一个set或者map前,一般都先调用get方法判断一下,现在使用multi系列,直接加入就可以了。

 

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

put(), putAll()clear()values()

 

 

有些有点区别,比如说,get()返回Collection<V>而不是Vremove(K)变成remove(K,V) removeAll(K)keySet()变成keys()entrySet()变成entries()

 

public static void main(String[] args) {

Map<String, Integer> m =new TreeMap<String, Integer>();

for (String word : args) {

Integer freq = m.get(word);

//以前加入之前总是要判断

m.put(word, (freq == null ? 1 : freq + 1));

}

System.out.println(m);

}

 

 

 

3.  BiMap bidirectional map)键和值都是唯一的,所以可以双向转换

BiMap implementationsEnumBiMap, EnumHashBiMap, HashBiMap, ImmutableBiMap

 

以前:

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

       } 

      } 

  

      //根据value获取key

    public static int getElementNumber(String elementName) { 

      return NAME_TO_NUMBER.get(elementName); 

    } 

      

    //根据num类型的key获取

    public static String getElementName(int elementNumber) { 

     return NUMBER_TO_NAME.get(elementNumber); 

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

  }

 现在:

static {

      NUMBER_TO_NAME_BIMAP = HashBiMap.create();

      NUMBER_TO_NAME_BIMAP.put(1, "Hydrogen");

      NUMBER_TO_NAME_BIMAP.put(2, "Helium");

      NUMBER_TO_NAME_BIMAP.put(3, "Lithium");

   }

  

   //更好,如果是数据量比较小,直接使用ImmutableBiMap.of更方便

private static final BiMap<Integer,String> NUMBER_TO_NAME_BIMAP1 

       = new ImmutableBiMap.Builder<Integer,String>() 

           .put(1, "Hydrogen") 

           .put(2, "Helium") 

           .put(3, "Lithium").build(); 

 

   public static int getElementNumber1(String elementName) {

      return NUMBER_TO_NAME_BIMAP.inverse().get(elementName);

   }

 

   public static String getElementName1(int elementNumber) {

      return NUMBER_TO_NAME_BIMAP.get(elementNumber);

   }

 

4.  MapMaker

一个ConcurrentMap的构建者,提供下列各种组合(soft/weakvaluessoft/weakkeys,超时时间),需要的时候,可以指定自己的处理函数,相比较于WeakHashMap,他更好用,更强大。

 

http://www./topic/670414

 

  1.   interface StudentDao {   
  2.     Information query(String name);   
  3. }   
  4.   
  5. class StudentDaoImpl implements StudentDao {   
  6.     // 真正去查数据库的实现类 代码省略   
  7. }   
  8. // 装饰器   
  9. class CachedStudentDao implements StudentDao {   
  10.     private final StudentDao studentDao;   
  11.     private final ConcurrentMap<String, Information> cache;   
  12.   
  13.     public CachedStudentDao(final StudentDao studentDao) {   
  14.         Preconditions.checkNotNull(studentDao, "studentDao");   
  15.         this.studentDao = studentDao;   
  16.            
  17.         this.cache = new MapMaker() // 构建一个 computingMap   
  18.             .expiration(60, TimeUnit.SECONDS) // 元素60秒过期   
  19.             .makeComputingMap(new Function<String, Information>(){   
  20.                 @Override  
  21.                 public Information apply(String name) {   
  22.                     return studentDao.query(name);   
  23.                 }   
  24.             });   
  25.             // 传入匿名Function自定义缓存的初始化。如果缓存中没有name对应的数据,则调用真正的dao去数据库查找数据,同时缓存结果。   
  26.     }   
  27.   
  28.     @Override  
  29.     public Information query(String name) {   
  30.         return cache.get(name); // computing cache中取结果   
  31.     }   
  32. }   
  33.   
  34. public void test() {   
  35.     StudentDao cachedStudentDao = new CachedStudentDao(studentDaoImpl);   
  36.     // 装饰了studenDaoImplcachedStudentDao具备了缓存结果的能力。   
  37. }  

 带你领略 Google Collections 2 http://jubin2002./blog/471698

 

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多