使用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 ...
随机推荐
- 一.MySQL安装
版本:linux7.6 一.编译安装 1.下载epel源 [root@db01 ~]# wget -O /etc/yum.repos.d/epel.repo https://mirrors.aliyu ...
- Java 问题定位工具 -- jps
概览 最近老大布置的任务就是质量加固,偶然看到了一些对于 Java 性能分析的介绍,因此,有了此篇学习笔记. JDK本身提供了很多方便的JVM性能调优监控工具,除了集成式的VisualVM和jCons ...
- MySQL中select、insert、update批量操作语句
项目中经常的需要使用批量操作语句对数据进行操作,使用批量语句的时候需要注意MySQL数据库的条件限制,这里主要是数据的大小限制,这里对批量插入.批量查找及批量更新的基础操作进行下简单的汇总. 1.批量 ...
- Maven构建 SpringMVC+Spring+MyBatis 环境整合
目录 1. Maven 项目搭建 2. Maven 插件生成 MyBatis 代码 3. 待续 ... 开发环境 开发环境请尽量保持一致,不一致的情况可能存在问题. JDK 1.7 MyEclipse ...
- vue数据变动监测
原文链接:https://blog.csdn.net/man_tutu/article/details/72148362 对象: 不能监测到: var vm = new Vue({ data:{ a: ...
- Testlink与MantisBT集成
Testlink与MantisBT集成 关于两者集成的文章网上有很多,但是有些文章可能是作者写的时候自己不理解或有纰漏,有些文章写得是不够详细导致在配置中遗漏什么导致不成功.经过一天的不停尝试,终于完 ...
- 算法 set / multiset -- lower_bound()的二分搜索
lower_bound() 在数组中搜索时 搜不到 返回 .end(), 若需要返回0,用upper_bound()-lower_bound() 若要返回下一个下标 则需要在set / multis ...
- 记一次webpack4.x项目配置
在自构建自己的个人页面的时候使用到webpack4,遇到了一些问题,查看了大佬们的文章以及官方文档,在这里总结一下. webpack比较基础的东西就不赘述了,代码里面的注释也会辅助说明,先看一下目录结 ...
- 如何在Rails6内通过Webpacker使用JavaScript; flatpicker日期时间组件选择器
如何在Rails6内通过Webpacker使用JavaScript; Rails6默认不再使用asset pipeline,改用Webpacker. 文件结构变化: 配置文件: webpacker.y ...
- mybatis多参数传递,延迟加载,缓存,注解开发
1.Mybatis的多参数传递方式 需求:更具id 和 名字查询用户: select * from user where id = ? and name = ?: 1):QueryVo 或者 User ...