使用Google Guava来编写优雅的代码 – 集合2

根据计划,从本篇开始会挑选Guava内部新增加的集合类来进行介绍。今天首先介绍的是Multiset:把重复的元素放入集合。JDK中Set定义了不能将重复的元素放入,那么Guava提供可以放入重复元素的Set的用意或者作用是什么呢?

首先让我们来看下面一段代码:

Map<String, Integer> counts = new HashMap<String, Integer>();
for (String word : words) {
    Integer count = counts.get(word);
    if (count == null) {
        counts.put(word, 1);
    } else {
        counts.put(word, count + 1);
    }
}

上面的代码实现的功能非常简单,用于记录字符串在数组中出现的次数。这种场景在实际的开发过程还是容易经常出现的,如果使用实现Multiset接口的具体类就可以很容易实现以上的功能需求:

Multiset<String> wordsMultiset = HashMultiset.create();
wordsMultiset.addAll(words);
//接下来就可以直接使用count方法来得到某个特定元素的个数了。

Multiset主要方法

Multiset接口定义的接口主要有:

  • add(E element) :向其中添加单个元素
  • add(E element,int occurrences) : 向其中添加指定个数的元素
  • count(Object element) : 返回给定参数元素的个数
  • remove(E element) : 移除一个元素,其count值 会响应减少
  • remove(E element,int occurrences): 移除相应个数的元素
  • elementSet() : 将不同的元素放入一个Set中
  • entrySet(): 类似与Map.entrySet 返回Set<Multiset.Entry>。包含的Entry支持使用getElement()和getCount()
  • setCount(E element ,int count): 设定某一个元素的重复次数
  • setCount(E element,int oldCount,int newCount): 将符合原有重复个数的元素修改为新的重复次数
  • retainAll(Collection c) : 保留出现在给定集合参数的所有的元素 * removeAll(Collection

    c) : 去除出现给给定集合参数的所有的元素

测试代码如下 :

/**
 * Test class for Multiset
 */

@Test
public class MultisetTest {


    @Test
    public void shouldAddElementTwoTimes() throws Exception {

        // given
        Multiset<String> multiset = HashMultiset.create();

        // when
        multiset.add("nothing");
        multiset.add("nothing");

        // then
        assertThat(multiset.count("nothing")).isEqualTo(2);
        assertThat(multiset.count("something")).isEqualTo(0);
    }

    @Test
    public void shouldUserCustomAddRemoveAndSetCount() throws Exception {

        // given
        Multiset<String> multiset = HashMultiset.create();

        // when
        multiset.add("ball");
        multiset.add("ball", 10);

        // then
        assertThat(multiset.count("ball")).isEqualTo(11);


        // when
        multiset.remove("ball", 5);

        // then
        assertThat(multiset.count("ball")).isEqualTo(6);


        // when
        multiset.setCount("ball", 2);

        // then
        assertThat(multiset.count("ball")).isEqualTo(2);
    }


    @Test
    public void shouldRetainOnlySelectedKeys() throws Exception {

        // given
        Multiset<String> multiset = HashMultiset.create();

        multiset.add("ball");
        multiset.add("ball");
        multiset.add("cow");
        multiset.setCount("twelve", 12);

        // when
        multiset.retainAll(Arrays.asList("ball", "horse"));

        assertThat(multiset.count("ball")).isEqualTo(2);
        assertThat(multiset.count("twelve")).isEqualTo(0);
    }

}

Multiset 不是Map

需要注意的是Multiset不是一个Map<E,Integer>,尽管Multiset提供一部分类似的功能实现。其它值得关注的差别有:

  • Multiset中的元素的重复个数只会是正数,且最大不会超过Integer.MAX_VALUE。设定计数为0的元素将不会出现multiset中,也不会出现elementSet()和entrySet()的返回结果中。
  • multiset.size() 方法返回的是所有的元素的总和,相当于是将所有重复的个数相加。如果需要知道每个元素的个数可以使用elementSet().size()得到.(因而调用add(E)方法会是multiset.size()增加1).
  • multiset.iterator() 会循环迭代每一个出现的元素,迭代的次数与multiset.size()相同。 iterates over each occurrence of each element, so the length of the iteration is equal to multiset.size().
  • Multiset 支持添加、移除多个元素以及重新设定元素的个数。执行setCount(element,0)相当于移除multiset中所有的相同元素。
  • 调用multiset.count(elem)方法时,如果该元素不在该集中,那么返回的结果只会是0。

实现类

Guava提供了Multiset的很多实现类,每一个实现类都对应这JDK的某一个map实现。具体如下表所示。

Map 对应的 Multiset实现 支持null
HashMap [HashMultiset](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/HashMultiset.html) Yes
TreeMap [TreeMultiset](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/TreeMultiset.html) Yes (如果comparator允许)
LinkedHashMap [LinkedHashMultiset](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/LinkedHashMultiset.html) Yes
ConcurrentHashMap [ConcurrentHashMultiset](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/ConcurrentHashMultiset.html) No
ImmutableMap [ImmutableMultiset](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/ImmutableMultiset.html) No
EnumMap [EnumMultiset](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/EnumMultiset.html)

除此以外还有ForwardingMultiset和ImmutableSortedMultiset,对于某些先增的类,需要关注其注解是否包含@Beta,那么这些类的API尚未稳定,调用过程需要小心。

本文对Guava中新增加的Multiset接口和实现类进行了简单的介绍,接下来我们将会介绍新增加的Multimap接口和其实现类的一些相关使用场景和使用方法,希望大家继续关注。

Google开源手机OS-live android使用截图

刚刚忙完最近的一个项目的预览版的发布。总算有点时间可以关注工作之外的一些事情了。在cnBeta上看到了Google android项目的X86平台的live cd版,今天中午抽空便先在virtualBox上使用了一把。

 

项目地址:live-android  

 

初次进入系统后,系统默认是英文的界面,需要接入Settings(设置)中修改本地语言为中文,系统重启之后就是中文了的。之前已经使用过了同事的Gone手机了。感觉轨迹球的设计不错,内置的一些功能也很不错了。加上现在更多的手机厂商开始支持Android系统了,甚至有更多的固定电话厂商和电视机顶盒厂商也开始支持Android了。这说明Android本身的影响还是很巨大的。

 

废话不多说,上图:
  1,浏览器界面
android-webbrower.png
 

继续阅读“Google开源手机OS-live android使用截图”