/**
* 常规思路:求两个无向图邻接表交集,前一种方法过于复杂.不对顶点序号做出改变,直接混合两个邻接表,然后执行相对的顶点序号修改,
* 同样能够保持两个文件顶点一一对应的关系,
* 但是新增顶点就会散布在新生成的混合文件内,需要进行对比找出,相比下这种方法更符合常规思路,直接把邻接表作为参数,复用时会有问题!!!!!改成文件名! 还有就是并发异常!
*
* @param srcFile
* @param incFile
* @return
* @throws IOException
* @throws NumberFormatException
*/
public static TreeMap<Integer, HashSet<Integer>> joinUndirAdjList2(
String srcFile, String incFile) throws NumberFormatException,
IOException {
TreeMap<Integer, HashSet<Integer>> mixedAdjList = AdjacencyList
.constructUnDirectedAdjList(srcFile);
try {
TreeMap<Integer, HashSet<Integer>> incAdjList = AdjacencyList
.constructUnDirectedAdjList(incFile); // 构建与新增文件对应的原始邻接表
for (Map.Entry<Integer, HashSet<Integer>> e : incAdjList.entrySet()) {
HashSet<Integer> values = e.getValue();
if(e.getKey()==9703336)
System.out.println("Test");
if (mixedAdjList.containsKey(e.getKey())) { // 如果src包含该key
for (Integer value : values) {
if (mixedAdjList.get(e.getKey()).contains(value))
continue; // 该新增边重复则跳过
if (mixedAdjList.containsKey(value)) { // 1.如果新增顶点和端点都在srcAdjList中且边不重复,则增加
mixedAdjList.get(e.getKey()).add(value);
mixedAdjList.get(value).add(e.getKey());
} else { // 2.如果新增顶点在,端点不在srcAdjList中,则增加
HashSet<Integer> newValues = new HashSet<Integer>();
newValues.add(e.getKey());
mixedAdjList.put(value, newValues);
mixedAdjList.get(e.getKey()).add(value);
}
}
} else {
for (Integer value : values) {
if (mixedAdjList.containsKey(value)) { // 3.如果新增key不在而value在
HashSet<Integer> newKeyValues = new HashSet<Integer>();
newKeyValues.add(value);
mixedAdjList.put(e.getKey(), newKeyValues); //这种做法会在第一个value生成keyValue对,但在第2个的时候生成新的kv对将前一个覆盖!
//比如27 | 51 39,假设mixedAdjList包含51,不包含<27,51>时会生成<27,51>,到39时会生成新的<27,39>,put会覆盖以前的<27,51>!
mixedAdjList.get(value).add(e.getKey());
} else {
HashSet<Integer> newKeyValues = new HashSet<Integer>(); // 4.如果新增key不在且value也不在
newKeyValues.add(e.getKey());
mixedAdjList.put(value, newKeyValues);
HashSet<Integer> newKeyValues2 = new HashSet<Integer>();
newKeyValues2.add(value);
mixedAdjList.put(e.getKey(), newKeyValues2);
}
}
}
}
} catch (NumberFormatException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(mixedAdjList.get(9703336));
return mixedAdjList;
}
总结: put的时候一定要确保这个key当前是不存在的,否则可能会覆盖以前的value!
集合使用常见错误总结:
1.容器复用问题.(Java的指针?)
2.并发错误(java.util.ConcurrentModificationException),尚未厘清原因.
3.put之前要确保key值不存在,否则会覆盖原有的value值!!!!
分享到:
相关推荐
C++hashmap的使用实例
HashMap为什么是线程不安全的?如何解决HashMap的线程不安全问题?
HashMap介绍和使用
hashMap排序,hashmap使用还是比较频繁。这时自己写的一个实现hashmap排序的例子
hashmap实例 hashmap实例hashmap实例hashmap实例
hashmap相关的面试题
HashMap数据结构,HashMap的构造方法,HashMap的put,HashMap的get
使用jQuery开发HashMap,包含一些基本的功能。
HashMap是android中一种小型存储类,写了一个简单的实例,希望能对有兴趣的朋友有用。
hashmap中hash函数的构造问题,提供了各种构造方法。以及比较函数的构造 挺适合入门学习的
高级程序员必会的HashMap的线程安全问题,适用于0~2年的
liballoc 中的 hashmap 默认使用 SipHash,它并没有我们想要的那么快。在编译器中,我们并不真正担心 DOS 尝试,因此我们使用快速非加密哈希。 这与 Firefox 使用的算法相同——它是一种不基于任何广为人知的算法的...
Go的hashmap使用加密随机种子,散列提示,开放寻址和罗宾汉哈希
HashMap存放.doc
看完这篇 HashMap,和面试官扯皮就没问题了 - HashMap 概述 - HashMap 和 HashTable 的区别 - 相同点 - 不同点 - HashMap 和 HashSet 的区别 - HashMap 底层结构 - AbstractMap 类 - Map 接口 - 重要内部类...
模拟java中的HashMap类js类对象,可以与js的Array类对象配合使用
HashMap是一个散列桶(数组和链表),它存储的内容是键值对(key-value)映射HashMap采用了数组和链表的数据结构,能在查询和修改方便继承了数组的线性查找和链表的寻址修改HashMap是非synchronized,所以HashMap很快...
Java语言使用hashmap实现向购物车添加删除修改商品,显示商品信息
Hashmap详解
HashMap是Java中非常常用的一种数据结构,它实现了Map接口,用于存储键值对。HashMap内部使用哈希表来实现,通过将键映射到哈希表中...但是,在使用HashMap时需要注意线程安全问题,并合理设计哈希函数以避免哈希冲突。