使用Maps与Sets处理集合的交差运算
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处理集合的交差运算的更多相关文章
- 【转载】MDX Step by Step 读书笔记(四) - Working with Sets (使用集合)
1. Set - 元组的集合,在 Set 中的元组用逗号分开,Set 以花括号括起来,例如: { ([Product].[Category].[Accessories]), ([Product].[ ...
- 使用Stack堆栈集合大数据运算
使用Stack堆栈集合大数据运算 package com.sta.to; import java.util.Iterator; import java.util.Stack; public class ...
- 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 ...
- day06--元组、字典、集合与关系运算
今日内容: 1.元组 2.字典 3.集合与关系运算 元组: 用途:记录多个值,当多个值没有改的需求,此时用元组更适合. 定义方式:在()内用逗号分隔开多个任意类型的值. 变量名=tuple('') 切 ...
- 005-guava 集合-集合工具类-java.util.Collections中未包含的集合工具[Maps,Lists,Sets],Iterables、Multisets、Multimaps、Tables
一.概述 工具类与特定集合接口的对应关系归纳如下: 集合接口 属于JDK还是Guava 对应的Guava工具类 Collection JDK Collections2:不要和java.util.Col ...
- python3 第十五章 - 数据类型之Sets(集合)
python的官网里对集合的描述是: Python also includes a data type for sets. A set is an unordered collection with ...
- Lists, Maps and Sets in Java
ArrayList vs LinkedList vs Vector From the hierarchy diagram, they all implement List interface. The ...
- spark 集合交集差集运算
intersect except是spark提供的集合差集运算, 但是要求参与运算的两个dataframe,有相同的data Schema. 如果我想从 集合1(attribute1, attribu ...
- python基础操作_集合_三元运算
#使用操作文件的时候,可以使用with函数#with open('E:\info.txt','a+') as fr#fr这个值可以是任意值# :#for line in fr:'''with open ...
随机推荐
- linux编译链接找不到库文件的解决方法。
今天编译出现ld: 0706-006 Cannot find or open library file: -l xerces-c_static,ld:open(): A file or directo ...
- 浅谈装饰器(Python)
先来了解函数和执行函数在python的区别 我再重新定义一个函数,在函数前面加上@set_func 执行结果如下: 函数前面没有加@set_fun 执行结果如下: 是不是可以不修改原来的函 ...
- node一些相关
1.Node node的核心语言是JavaScript ,基于Google的V8引擎. 2.node使用 找到当前文件所在目录 node 文件名.js 直接用绝对路径 在当前目录打开命令窗口 3.n ...
- 从手机中导出apk
输入指令adb devices, 出现类似下面信息,说明设备连接成功. List of devices attached HT4C3JT00386 device 3.查看该手机所有安装包的包名, 输入 ...
- centos7.5升级openssh7.4到7.9
漏洞扫描工具扫描出openssh用户枚举漏洞,搜索资料得知无补丁和升级包,解决这个漏洞得安装漏洞修复之后的版本version>7.8. 环境 linux版本: CentOS Linux rele ...
- C# Finalize和Dispose的区别
一:总结 1.Finalize方法(C#中是析构函数,以下称析构函数)是用于释放非托管资源的,而托管资源会由GC自动回收.所以,我们也可以这样来区分 托管和非托管资源.所有会由GC自动回收的资源,就是 ...
- MySQL及navicat for mysql中文乱码
转载自:https://www.cnblogs.com/mufire/p/6697994.html 修改完之后记着重启mysql服务,在服务里边重启,即可生效! 全部使用utf8编码 MySQL中文乱 ...
- Vue-admin工作整理(十九):从数字渐变组件谈第三方JS库Count-to的使用
1.组件封装基础 npm install countup@latest 2.组件中使用id值 3.组件中获得dom 如何封装一个组件,在组件中用到需要传入HTML元素ID值的JS库时如何处理,如何获取 ...
- leetcode算法题01
最近求职需要重新刷算法题,从今天开始每天至少做一个leatcode的题 如果有更好的算法或者换了语言也会更新 题目: 给定一个整数数组和一个目标值,找出数组中和为目标值的两个数. 你可以假设每个输入只 ...
- Hadoop之HDFS概述
一.HDFS产生背景及定义 1.HDFS产生背景 随着数据量越来越大,在一个操作系统存不下所有的数据,那么就分配到更多的操作系统管理的磁盘中,但是不方便管理和维护,迫切需要一种系统来管理多台机器上的文 ...