使用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 ...
随机推荐
- java中的构造器
构造器是什么 1.构造器,也称构造方法.构造函数.作用是构造出来一个类的实例,确保对象得到初始化. 2.构造器的格式: 权限修饰符 类名(无参/有参){}. 3.根据有无参数,可分为无参构造 和有参构 ...
- SP913 QTREE2 - Query on a tree II
思路 第一个可以倍增,第二个讨论在a到lca的路径上还是lca到b的路径上, 倍增即可 代码 #include <cstdio> #include <algorithm> #i ...
- IIS简单的反向代理设置
下载IIS扩展 1.URL Rewrite 地址: https://www.iis.net/downloads/microsoft/url-rewrite 2.Application Request ...
- yii 邮箱封装
<?php class Mailer { private static $obj; private static $config; public static function getMaile ...
- 【python 3】 函数 进阶
函数进阶 1.函数命名空间和作用域 命名空间一共分为三种: 全局命名空间 局部命名空间 内置命名空间 *内置命名空间中存放了python解释器为我们提供的名字:input , print , str ...
- spark DAG 笔记
DAG,有向无环图,Directed Acyclic Graph的缩写,常用于建模. Spark中使用DAG对RDD的关系进行建模,描述了RDD的依赖关系,这种关系也被称之为lineage,RDD的依 ...
- ZT: C#不建类直接Json解析与取值
C#不建类直接Json解析与取值 2017年10月19日 15:58:22 圆圆娃哈哈 阅读数:701 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn. ...
- 第 10 章 容器监控 - 081 - Weave Scope 多主机监控
除了监控容器,Weave Scope 还可以监控 Docker Host 点击顶部 HOSTS 菜单项,地图将显示当前 host. 与容器类似,点击该 host 图标将显示详细信息 host 当前的资 ...
- Data Block Compression
The database can use table compression to eliminate duplicate values in a data block. This section d ...
- .class 缓存
项目用的是Ant. 场景: Class A{ private static final String HHH="hello"; } Class B{ public void met ...