import com.google.common.collect.MapDifference;
import com.google.common.collect.Maps;
import java.util.HashMap;
import java.util.Map;
public class differenceMap {
public static void main(String[] args) {
Map<String, String> map = new HashMap<>();
map.put("a1", "aaa");
map.put("a2", "bbb");
map.put("a3", "ccc");
Map<String, String> map1 = new HashMap<>();
map1.put("z1", "zzz");
map1.put("a1", "aaa");
map1.put("a2", "dra");
MapDifference differenceMap = Maps.difference(map, map1);
differenceMap.areEqual();
Map<String, MapDifference.ValueDifference<String>> entriesDiffering = differenceMap.entriesDiffering();
Map<String,String> entriesOnlyOnLeft = differenceMap.entriesOnlyOnLeft();
Map<String,String> entriesOnlyOnRight = differenceMap.entriesOnlyOnRight();
Map<String,String> entriesInCommon = differenceMap.entriesInCommon();
System.out.println("健在两集合存在,但值不同的");
for (Map.Entry<String, MapDifference.ValueDifference<String>> s : entriesDiffering.entrySet()) {
System.out.println(s.getKey()+"="+s.getValue().leftValue());
System.out.println(s.getKey()+"="+s.getValue().rightValue());
}
System.out.println("只在左边出现的");
for (Map.Entry<String,String> s :entriesOnlyOnLeft.entrySet()) {
System.out.println(s.getKey()+"="+s.getValue());
}
System.out.println("只在右边出现的");
for (Map.Entry<String,String> s :entriesOnlyOnRight.entrySet()) {
System.out.println(s.getKey()+"="+s.getValue());
}
System.out.println("两者共存的");
for (Map.Entry<String,String> s :entriesInCommon.entrySet()) {
System.out.println(s.getKey()+"="+s.getValue());
} }
}

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处理集合的交差运算的更多相关文章

  1. 【转载】MDX Step by Step 读书笔记(四) - Working with Sets (使用集合)

    1. Set  - 元组的集合,在 Set 中的元组用逗号分开,Set 以花括号括起来,例如: { ([Product].[Category].[Accessories]), ([Product].[ ...

  2. 使用Stack堆栈集合大数据运算

    使用Stack堆栈集合大数据运算 package com.sta.to; import java.util.Iterator; import java.util.Stack; public class ...

  3. python集合(set)的运算

    1.交集 In [1]: a = {1,2,3,4} In [2]: b = {3,4,5,6} In [3]: a & b Out[3]: {3, 4} In [4]: a.intersec ...

  4. day06--元组、字典、集合与关系运算

    今日内容: 1.元组 2.字典 3.集合与关系运算 元组: 用途:记录多个值,当多个值没有改的需求,此时用元组更适合. 定义方式:在()内用逗号分隔开多个任意类型的值. 变量名=tuple('') 切 ...

  5. 005-guava 集合-集合工具类-java.util.Collections中未包含的集合工具[Maps,Lists,Sets],Iterables、Multisets、Multimaps、Tables

    一.概述 工具类与特定集合接口的对应关系归纳如下: 集合接口 属于JDK还是Guava 对应的Guava工具类 Collection JDK Collections2:不要和java.util.Col ...

  6. python3 第十五章 - 数据类型之Sets(集合)

    python的官网里对集合的描述是: Python also includes a data type for sets. A set is an unordered collection with ...

  7. Lists, Maps and Sets in Java

    ArrayList vs LinkedList vs Vector From the hierarchy diagram, they all implement List interface. The ...

  8. spark 集合交集差集运算

    intersect except是spark提供的集合差集运算, 但是要求参与运算的两个dataframe,有相同的data Schema. 如果我想从 集合1(attribute1, attribu ...

  9. python基础操作_集合_三元运算

    #使用操作文件的时候,可以使用with函数#with open('E:\info.txt','a+') as fr#fr这个值可以是任意值# :#for line in fr:'''with open ...

随机推荐

  1. Java构造器与构建器的使用

    我们在平常类的构建过程中,可能会面临很多问题,可扩张性.安全性等等.想象一下,这样一个场景,我们现在要创建一个类,其中有6个属性,其中又有4个属性的值是不太确定的(可能某个对象就不需要其中的某个值), ...

  2. springBoot整合jpa

    https://blog.csdn.net/qq_35180973/article/details/82316438 总体来讲只是在service调用dao的时候用接口代替dao继承CrudRepos ...

  3. 关于html中的 script标签中的 代码写法有效性? easyui tabs的href不能载入内容页面

    script标签, 即 html中的 js脚本区域中: 它其实就是一个 普通的 html标签, 在 html 渲染器 parser 看来, 它跟其他任何的普通 的 html标签 , 比如 p 标签, ...

  4. 【ActiveReports 大数据分析报告】用数据分析的手段告诉你,复联4有多火爆?

    消失的人们会回来吗,奇异博士所说的1400万分之一可能性究竟是什么,还会有谁逝去? 4月24日零时,随着万众期待的<复仇者联盟4>(以下简称<复联4>)正式上映,一切谜底都将揭 ...

  5. ASP.NET Core API 接收参数去掉烦人的 [FromBody]

    在测试ASP.NET Core API 项目的时候,发现后台接口参数为类型对象,对于PostMan和Ajax的Post方法传Json数据都获取不到相应的值,后来在类型参数前面加了一个[FromBody ...

  6. Yum安装时出现 The program yum-complete-transaction is found in the yum-utils package

    yum安装时出现 The program yum-complete-transaction is found in the yum-utils package yum之后,会显示上信息,并且最终执行结 ...

  7. @keyframs实现图片gif效果

    页面中使用动效图 一般让设计出一个gif格式的图,但是git图效果都很差,有一个替代gif图做动效的方法:使用@keyframes 具体思路: 1.设计两个互斥的图片(相当于把gif图分割成一帧一帧的 ...

  8. 悲观并发 乐观并发 Entity Framework Core中的并发处理

    悲观并发策略 A用户发起一个请求   开启了事务 查询到了某一条数据 进行修改     在A提交事务之前 其他人都不能对这条数据进行修改 这种策略最常见的一个问题就是死锁  比如A修改X记录,B修改Y ...

  9. RecyclerView联动滑动失败

    RecyclerView联动滑动失败 我们在做Recyclerview联动滑动的时候,就是左边一个RecyclerView右边一个RecyclerView 我们希望左边的RecyclerView可以和 ...

  10. 初步接触gulp

    首先是安装nodejs,通过nodejs的npm全局安装和项目安装gulp,其次在项目里安装所需要的gulp插件,然后新建gulp的配置文件gulpfile.js并写好配置信息(定义gulp任务),最 ...