guava之MultiSet、MultiMap和BiMap

MultiSet

和Set不同的是MultiSet可以把重复的元素放入集合,你可能会说这和 Set 接口的契约冲突,因为 Set 接口的JavaDoc里面规定不能放入重复元素。事实上,Multiset 并没有实现 java.util.Set 接口,它更像是一个 Bag。普通的 Set 就像这样 :[car, ship, bike],而 Multiset 会是这样 : [car x 2, ship x 6, bike x 3]。Multiset有一个有用的功能,就是跟踪每种对象的数量,所以你可以用来进行数字统计。

常用实现 Multiset 接口的类有:

  • HashMultiset: 元素存放于 HashMap
  • LinkedHashMultiset: 元素存放于 LinkedHashMap,即元素的排列顺序由第一次放入的顺序决定
  • TreeMultiset:元素被排序存放于TreeMap
  • EnumMultiset: 元素必须是 enum 类型
  • ImmutableMultiset: 不可修改的 Mutiset

Guava Collections 都是以 create 或是 of 这样的静态方法来构造对象。这是因为这些集合类大多有多个参数的私有构造方法,由于参数数目很多,客户代码程序员使用起来就很不方便。而且以这种方式可以返回原类型的子类型对象。另外,对于创建范型对象来讲,这种方式更加简洁。

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(Collectionc) : 去除出现给给定集合参数的所有的元素
import java.util.Set;

import com.google.common.collect.HashMultiset;
import com.google.common.collect.Multiset;

/**
 * 统计单词出现的次数
 * multiset 无序可以重复 使用count方法可以统计单词出现的次数
 * @author Administrator
 *
 */
public class Demo03 {
    public static void main(String[] args) {

        String str = "this is a cat and that is a mice where is the food ";
        String[] arr = str.split(" ");
        //存储到MutiSet中
        Multiset<String> set = HashMultiset.create();
        for(String temp:arr){
            set.add(temp);
        }
        System.out.println(set.size());
        set.remove("is",1); 

        Set<String> letters = set.elementSet();
        for(String temp:letters){
            //因为前面单词is已经移除一次了,所以打印出的会是2
            System.err.println(temp+"--"+set.count(temp));
        }


//      for(Multiset.Entry<String> temp:set.entrySet()){
//          System.out.println(temp.getElement()+"--"+temp.getCount());
//      }
    }

}

MultiMap

有时候我们需要这样的数据类型Map(String,Collection(String)),也就是所谓的一键多值,guava中的Multimap就是为了解决这类问题的。Multimap提供了丰富的实现,所以你可以用它来替代程序里的Map(K, Collection(V)),具体的实现如下:

                  这里写图片描述

import java.util.Collection;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;

/**
 * 测试Multimap 其是map的延伸,不过其中的键可以重复,意思就是可以一键多值
 * @author Administrator
 *
 */
public class Demo04 {

    public static void main(String[] args) {
        Multimap<String,String> multimap = ArrayListMultimap.create();
          // 添加键值对
          multimap.put("Fruits", "Bannana"); 
          // 给Fruits元素添加另一个元素 
          multimap.put("Fruits", "Apple");  
          multimap.put("Fruits", "Pear");  
          multimap.put("Vegetables", "Carrot");  

          System.out.println(multimap.size());  //size为4说明就算键相同,值也不会被覆盖
          Collection<String> col = multimap.get("Fruits");
          System.out.println(col);
          // 移除一个值 
          multimap.remove("Fruits","Pear");  
          System.out.println(multimap.get("Fruits")); // [Bannana, Pear]  

          // 移除所有的值 
          multimap.removeAll("Fruits");  
          System.out.println(multimap.get("Fruits")); // [] (Empty Collection

    }

}
输出结果:4
        [Bannana, Apple, Pear]
        [Bannana, Apple]
        []

BiMap

我们知道Map是一种键值对映射,这个映射是键到值的映射,而BiMap首先也是一种Map,他的特别之处在于,既提供键到值的映射,也提供值到键的映射,所以它是双向Map。BiMap的值键对的Map可以通过inverse()方法得到。

BiMap的常用实现有:
    HashBiMap: key 集合与 value 集合都有 HashMap 实现
    EnumBiMap: key 与 value 都必须是 enum 类型
    ImmutableBiMap: 不可修改的 BiMap
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;


/**
 * 测试Bimap,双向map,也就是键和值都不能重复,而且可以通过值来找键
 * @author Administrator
 *
 */
public class Demo05 {
    public static void main(String[] args) {

        BiMap<String,String> map = HashBiMap.create();
        map.put("星期一","Monday");
        map.put("星期二","Tuesday");
        map.put("星期三","Wednesday");
        map.put("星期四","Thursday");
        map.put("星期五","Friday");
        map.put("星期六","Saturday");
        map.put("星期日","Sunday");

        System.out.println("星期日的英文名是" + map.get("星期日"));
        System.out.println("Sunday的中文是" + map.inverse().get("Sunday"));
        System.out.println(map.inverse().inverse()==map);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值