使用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 }
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处理集合的交差运算的主要内容,如果未能解决你的问题,请参考以下文章
ID、标签 null 或父 ID 与 com.google.android.gms.maps.MapFragment 的另一个片段重复