使用Maps与Sets处理集合的交差运算

 1 import com.google.common.collect.MapDifference;
 2 import com.google.common.collect.Maps;
 3 import java.util.HashMap;
 4 import java.util.Map;
 5 public class differenceMap {
 6     public static void main(String[] args) {
 7         Map<String, String> map = new HashMap<>();
 8         map.put("a1", "aaa");
 9         map.put("a2", "bbb");
10         map.put("a3", "ccc");
11         Map<String, String> map1 = new HashMap<>();
12         map1.put("z1", "zzz");
13         map1.put("a1", "aaa");
14         map1.put("a2", "dra");
15         MapDifference differenceMap = Maps.difference(map, map1);
16         differenceMap.areEqual();
17         Map<String, MapDifference.ValueDifference<String>> entriesDiffering = differenceMap.entriesDiffering();
18         Map<String,String> entriesOnlyOnLeft = differenceMap.entriesOnlyOnLeft();
19         Map<String,String> entriesOnlyOnRight = differenceMap.entriesOnlyOnRight();
20         Map<String,String> entriesInCommon = differenceMap.entriesInCommon();
21         System.out.println("健在两集合存在,但值不同的");
22         for (Map.Entry<String, MapDifference.ValueDifference<String>> s : entriesDiffering.entrySet()) {
23             System.out.println(s.getKey()+"="+s.getValue().leftValue());
24             System.out.println(s.getKey()+"="+s.getValue().rightValue());
25         }
26         System.out.println("只在左边出现的");
27         for (Map.Entry<String,String> s :entriesOnlyOnLeft.entrySet()) {
28             System.out.println(s.getKey()+"="+s.getValue());
29         }
30         System.out.println("只在右边出现的");
31         for (Map.Entry<String,String> s :entriesOnlyOnRight.entrySet()) {
32             System.out.println(s.getKey()+"="+s.getValue());
33         }
34         System.out.println("两者共存的");
35         for (Map.Entry<String,String> s :entriesInCommon.entrySet()) {
36             System.out.println(s.getKey()+"="+s.getValue());
37         }
38
39     }
40 }

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);}
 


时间: 2025-01-07 12:44:13

使用Maps与Sets处理集合的交差运算的相关文章

Redis Sets无序集合 存储操作方法

欢迎大家加入 459479177QQ群进行交流 这次介绍的是Sets无序集合 老生常谈,使用redis-cli进入我们的redis服务 [[email protected] ~]# redis-cli  127.0.0.1:6379> 1>sadd 方法:sadd key value [value...] 描述:往key添加一个或多个value,如果value元素存在则忽略 127.0.0.1:6379> smembers skey1 (empty list or set) 127.0.

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

使用Stack堆栈集合大数据运算 package com.sta.to; import java.util.Iterator; import java.util.Stack; public class DaMax { public void jiaFa(String value1, String value2) { /** * 更多资料欢迎浏览凯哥学堂官网:http://kaige123.com * @author 小沫 */ // 把字符串用toCharArray拆成字符 char[] c1

集合定义 赋值 运算 特殊操作注意事项..

概念: delphi中的集合是对数学中集合概念的简单实现.要求是集合中的元素必须同类型,且必须是序数类型,且集合中可能的元素个数不能大于255. 集合是P a s c a l特有的数据类型,在Visual Basic.C或C + +都没有(虽然C++ Builder提供了一种模板类称为集合,它模仿P a s c a l集合的行为). 集合是由具有某些共同特征的元素构成的一个整体.在pascal中,一个集合是由具有同一有序类型的一组数据元素所组成,这一有序类型称为该集合的基类型. 类型的定义和变量

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

#使用操作文件的时候,可以使用with函数#with open('E:\info.txt','a+') as fr#fr这个值可以是任意值# :#for line in fr:'''with open('a.txt','r') as f: f.read()上下这两行代码是一样的原理f=open('a.txt','r')f.read()f.close()''''''f=open('a.txt','a')f.seek(0)移动文件指针到第一个f.truncate()清空文件的内容'''#同时打开两个

2.4.2 集合操作与运算

1 集合元素增加与删除 使用集合对象的add()方法可以为其增加新元素,如果该元素已存在于集合则忽略该操作:update()方法用于合并另外一个集合中的额元素到当前集合中.例如: 1 >>> s = {1,2,3} 2 >>> s.add(3) 3 >>> s 4 {1, 2, 3} 5 >>> #添加元素,重复元素自动忽略 6 >>> 7 >>> s.update({3,4}) #更新当前集合,自

JAVA集合框架

收藏 查看我的收藏 146有用+1 56 编辑 Java,是由Sun Microsystems公司于1995年5月推出的Java程序设计语言和Java平台的总称.用Java实现的HotJava浏览器(支持Java applet)显示了Java的魅力:跨平台.动态的Web.Internet计算.从此,Java被广泛接受并推动了Web的迅速发展,常用的浏览器现在均支持Java applet.集合框架是为表示和操作集合而规定的一种统一的标准的体系结构.任何集合框架都包含三大块内容:对外的接口.接口的实

Java集合容器简介

Java集合容器主要有以下几类: 1,内置容器:数组 2,list容器:Vetor,Stack,ArrayList,LinkedList, CopyOnWriteArrayList(1.5),AttributeList(1.5),RoleList(1.5),RoleUnresolvedList(1.5), ConcurrentLinkedQueue(1.5),ArrayBlockingQueue(1.5),LinkedBlockingQueue(1.5), PriorityQueue(1.5),

进击的雨燕--------------集合类型

Swift 语言提供Arrays.Sets和Dictionaries三种基本的集合类型用来存储集合数据.数组(Arrays)是有序数据的集.集合(Sets)是无序无重复数据的集.字典(Dictionaries)是无序的键值对的集. Swift 语言中的Arrays.Sets和Dictionaries中存储的数据值类型必须明确.这意味着我们不能把不正确的数据类型插入其中.同时这也说明我们完全可以对取回值的类型非常自信. 注意:Swift 的Arrays.Sets和Dictionaries类型被实现

一个简单的Java集合范围过滤的多个方式对比

在一个项目里面有这么一个技术需求: 1.集合中元素个数,10M 2.根据上限和下限从一个Set中过滤出满足要求的元素集合. 实际这个是个很典型的技术要求, 之前的项目也遇见过,但是因为当时的类库不多, 都是直接手写实现的. 方式基本等同于第一个方式. 在这个过程中, 我写了四个方式, 基本记录到下面. 第一个方式:对Set进行迭代器遍历, 判断每个元素是否都在上限和下限范围中.如果满足则添加到结果集合中, 最后返回结果集合.             测试效果:集合大小100K, 运算时间 300