使用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 ...
随机推荐
- 如何安装mariadb服务器和解决 can't connect to local mysql server through socket...
故障现象, ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.s ...
- 好玩图像pil处理
pil库的学习总结 #__author:'lwq'#date: 2018/11/15 from PIL import Image,ImageFilter,ImageDraw,ImageFont ### ...
- 初学者易上手的SSH-spring 01控制反转(IOC)
这章开始学习SSH中最后的一个框架spring.Spring是一个开放源代码的设计层面框架,他解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用. 首先就来学习一下I ...
- Windows 下Jenkins进程误删,如何重启
手残误删了Jenkins运行的java进程,结果.... 用管理员身份启动cmd 然后进入jenkins目录.运行 net start jenkins 否则会报系统错误5 延伸: net stop j ...
- Kotlin 接口
Kotlin 接口与 Java 8 类似,使用 interface 关键字定义接口,允许方法有默认实现: interface MyInterface { fun bar() // 未实现 fun fo ...
- Js原生封装选项卡组件
class MyTab extends HTMLElement{ //创建一个类名MyTab constructor(){ //构造函数 super(); //指向父类构造函数,必须要有的 const ...
- python 2.7 读写 opc数据
运行环境 python2.7+window server2008+keep server 1.安装OpenOPC a> 下载 OpenOPC-1.3.1.win32-py2.7 (1).exe ...
- [redis] redis 命令
- YY的GCD
YY的GCD 给出T个询问,询问\(\sum_{i=1}^N\sum_{j=1}^M(gcd(i,j)\in prime)\),T = 10000,N, M <= 10000000. 解 显然质 ...
- Linux基础命令mkdir
mkdir /home/ceshi home目录下创建测试目录 mkdir -p /home/ceshi1/ceshi home目录下递归创建 mkdir /home/ceshi2 ...