使用Maps与Sets处理集合的交差运算

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Maps与Sets处理集合的交差运算相关的知识,希望对你有一定的参考价值。

技术分享
 1 import com.google.common.collect.MapDifference;
 2 import com.google.common.collect.Maps;
 3 import java.util.HashMap;
 4 import java.util.Map;
 5 public class differenceMap {
 6     public static void main(String[] args) {
 7         Map<String, String> map = new HashMap<>();
 8         map.put("a1", "aaa");
 9         map.put("a2", "bbb");
10         map.put("a3", "ccc");
11         Map<String, String> map1 = new HashMap<>();
12         map1.put("z1", "zzz");
13         map1.put("a1", "aaa");
14         map1.put("a2", "dra");
15         MapDifference differenceMap = Maps.difference(map, map1);
16         differenceMap.areEqual();
17         Map<String, MapDifference.ValueDifference<String>> entriesDiffering = differenceMap.entriesDiffering();
18         Map<String,String> entriesOnlyOnLeft = differenceMap.entriesOnlyOnLeft();
19         Map<String,String> entriesOnlyOnRight = differenceMap.entriesOnlyOnRight();
20         Map<String,String> entriesInCommon = differenceMap.entriesInCommon();
21         System.out.println("健在两集合存在,但值不同的");
22         for (Map.Entry<String, MapDifference.ValueDifference<String>> s : entriesDiffering.entrySet()) {
23             System.out.println(s.getKey()+"="+s.getValue().leftValue());
24             System.out.println(s.getKey()+"="+s.getValue().rightValue());
25         }
26         System.out.println("只在左边出现的");
27         for (Map.Entry<String,String> s :entriesOnlyOnLeft.entrySet()) {
28             System.out.println(s.getKey()+"="+s.getValue());
29         }
30         System.out.println("只在右边出现的");
31         for (Map.Entry<String,String> s :entriesOnlyOnRight.entrySet()) {
32             System.out.println(s.getKey()+"="+s.getValue());
33         }
34         System.out.println("两者共存的");
35         for (Map.Entry<String,String> s :entriesInCommon.entrySet()) {
36             System.out.println(s.getKey()+"="+s.getValue());
37         }
38 
39     }
40 }
Java Code

Guava Maps的提供了非常强大的处理Map运算的方法,上面是他的一个简单的使用用例,下面我们来看下它的源码:

一 从构造函数看起:

 public static <K, V> MapDifference<K, V> difference(

Map<? extends K, ? extends V> left, Map<? extends K, ? extends V> right) {

  if (left instanceof SortedMap) {               首先判断左边集合是不是排序集合,我们先来看不是排序集合的情况,
SortedMap<K, ? extends V> sortedLeft = (SortedMap<K, ? extends V>) left;
SortedMapDifference<K, V> result = difference(sortedLeft, right);
return result;
}
return difference(left, right, Equivalence.equals()); Equivalence.equals作为判断两个元素是否相等的标准,详情参加另一篇博客Base包Equivalence
}
public static <K, V> MapDifference<K, V> difference(   我们其实可以使用这个函数传入我们想要的Equivalence
Map<? extends K, ? extends V> left,
Map<? extends K, ? extends V> right,
Equivalence<? super V> valueEquivalence) {
Preconditions.checkNotNull(valueEquivalence); 由于外界可以直接调用,判断参数,编写程序中,我们要知道那些函数可以被外界调用(进行参数检查),只是内部调用
Map<K, V> onlyOnLeft = newLinkedHashMap(); 内部调用的函数只需要在入口处进行参数判别。
Map<K, V> onlyOnRight = new LinkedHashMap<K, V>(right); // will whittle it down
Map<K, V> onBoth = newLinkedHashMap();
Map<K, MapDifference.ValueDifference<V>> differences = newLinkedHashMap(); 为什么要用LinkedHashMap呢?
解释一下,HashMap是不能保证插入的元素顺序的,LinkedHashMap可以,这样我们遍历结果时,会得到和原始Map形同的键顺序!!更符合人们的阅读习惯!漂亮的代码!
doDifference(left, right, valueEquivalence, onlyOnLeft, onlyOnRight, onBoth, differences); 这个函数是计算函数
return new MapDifferenceImpl<K, V>(onlyOnLeft, onlyOnRight, onBoth, differences); 这仅仅是个保存信息用的,没什么,感兴趣的自己看
}

private static <K, V> void doDifference(
    Map<? extends K, ? extends V> left,
Map<? extends K, ? extends V> right,
Equivalence<? super V> valueEquivalence,
Map<K, V> onlyOnLeft,
Map<K, V> onlyOnRight,
Map<K, V> onBoth,
Map<K, MapDifference.ValueDifference<V>> differences) {
for (Entry<? extends K, ? extends V> entry : left.entrySet()) { 也就是个遍历。
K leftKey = entry.getKey();
V leftValue = entry.getValue();
if (right.containsKey(leftKey)) {
V rightValue = onlyOnRight.remove(leftKey);
if (valueEquivalence.equivalent(leftValue, rightValue)) {
onBoth.put(leftKey, leftValue);
} else {
differences.put(leftKey, ValueDifferenceImpl.create(leftValue, rightValue));
}
} else {
onlyOnLeft.put(leftKey, leftValue);
}
}
}
public static <K, V> SortedMapDifference<K, V> difference(  这个就是排序了的Map最后掉用的函数,区别就是使用了TreeMap。自动保持顺序。
SortedMap<K, ? extends V> left, Map<? extends K, ? extends V> right) {
checkNotNull(left);
checkNotNull(right);
Comparator<? super K> comparator = orNaturalOrder(left.comparator());
SortedMap<K, V> onlyOnLeft = Maps.newTreeMap(comparator);
SortedMap<K, V> onlyOnRight = Maps.newTreeMap(comparator);
onlyOnRight.putAll(right); // will whittle it down
SortedMap<K, V> onBoth = Maps.newTreeMap(comparator);
SortedMap<K, MapDifference.ValueDifference<V>> differences = Maps.newTreeMap(comparator);
doDifference(left, right, Equivalence.equals(), onlyOnLeft, onlyOnRight, onBoth, differences);
return new SortedMapDifferenceImpl<K, V>(onlyOnLeft, onlyOnRight, onBoth, differences);
}
 



























































以上是关于使用Maps与Sets处理集合的交差运算的主要内容,如果未能解决你的问题,请参考以下文章

集合的并交差对称差运算

TOJ 1743集合运算(set集合并交差的运用)

在 Fragment 中恢复 Google Maps 状态

ES6 Maps and Sets:如何有效地索引对象键?

ID、标签 null 或父 ID 与 com.google.android.gms.maps.MapFragment 的另一个片段重复

python中集合的运算(转)