Java|Guava中这些Map的优秀操作,让我的代码量减少了50%( 三 )


Multimap<String Integer> multimap = ArrayListMultimap.create();multimap.put(\"day\"1);multimap.put(\"day\"2);multimap.put(\"day\"8);multimap.put(\"month\"3);

打印这个Multimap的内容 , 可以直观的看到每个key对应的都是一个集合:
{month=[3
day=[1 2 8


1、获取值的集合在上面的操作中 , 创建的普通Multimap的get(key)方法将返回一个Collection类型的集合:
Collection<Integer> day = multimap.get(\"day\");

如果在创建时指定为ArrayListMultimap类型 , 那么get方法将返回一个List:
ArrayListMultimap<String Integer> multimap = ArrayListMultimap.create();
List<Integer> day = multimap.get(\"day\");

同理 , 你还可以创建HashMultimap、TreeMultimap等类型的Multimap 。
Multimap的get方法会返回一个非null的集合 , 但是这个集合的内容可能是空 , 看一下下面的例子:
List<Integer> day = multimap.get(\"day\");
List<Integer> year = multimap.get(\"year\");
System.out.println(day);
System.out.println(year);

打印结果:
[1 2 8

[


2、操作get后的集合和BiMap的使用类似 , 使用get方法返回的集合也不是一个独立的对象 , 可以理解为集合视图的关联 , 对这个新集合的操作仍然会作用于原始的Multimap上 , 看一下下面的例子:
ArrayListMultimap<String Integer> multimap = ArrayListMultimap.create();multimap.put(\"day\"1);multimap.put(\"day\"2);multimap.put(\"day\"8);multimap.put(\"month\"3);
List<Integer> day = multimap.get(\"day\");
List<Integer> month = multimap.get(\"month\");
day.remove(0);//这个0是下标month.add(12);
System.out.println(multimap);

查看修改后的结果:
{month=[3 12
day=[2 8


3、转换为Map使用asMap方法 , 可以将Multimap转换为Map的形式 , 同样这个Map也可以看做一个关联的视图 , 在这个Map上的操作会作用于原始的Multimap 。
Map<String Collection<Integer>> map = multimap.asMap();for (String key : map.keySet()) {    System.out.println(key+\" : \"+map.get(key));
map.get(\"day\").add(20);System.out.println(multimap);

执行结果:
month : [3
day : [1 2 8
{month=[3
day=[1 2 8 20


4、数量问题Multimap中的数量在使用中也有些容易混淆的地方 , 先看下面的例子:
System.out.println(multimap.size());System.out.println(multimap.entries().size());for (Map.Entry<String Integer> entry : multimap.entries()) {    System.out.println(entry.getKey()+\"\"+entry.getValue());


打印结果:
44month3day1day2day8

这是因为size()方法返回的是所有key到单个value的映射 , 因此结果为4 , entries()方法同理 , 返回的是key和单个value的键值对集合 。 但是它的keySet中保存的是不同的key的个数 , 例如下面这行代码打印的结果就会是2 。
System.out.println(multimap.keySet().size());

再看看将它转换为Map后 , 数量则会发生变化:
Set<Map.Entry<String Collection<Integer>>> entries = multimap.asMap().entrySet();
System.out.println(entries.size());

代码运行结果是2 , 因为它得到的是key到Collection的映射关系 。
RangeMap - 范围Map先看一个例子 , 假设我们要根据分数对考试成绩进行分类 , 那么代码中就会出现这样丑陋的if-else:
public static String getRank(int score){    if (0<=score && score<60)        return \"fail\";    else if (60<=score && score<=90)        return \"satisfactory\";    else if (90<score && score<=100)        return \"excellent\";    return null;


而guava中的RangeMap描述了一种从区间到特定值的映射关系 , 让我们能够以更为优雅的方法来书写代码 。 下面用RangeMap改造上面的代码并进行测试: