最近在做一个老系统,由于表的信息不明确, 在数据库拿二个表的时候产生了笛卡尔联结,由于重复数据只有三条. 而这二个表的列数据比较固定. 所以决定取出来在后端去重。 数据类型是以List<HashMap> 进行接收的。 现在我把它合并成一条HashMap(然而后来我们没有采用这种方式, 只是记录下来突如其来的想法 ~). 测试代码如下:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
public class Test {
public void testMergeMap(){
List<Map<String, String>> list = new ArrayList<>();
Map<String, String> m1 = new HashMap<>();
m1.put("fruits", "apple");
m1.put("others", "hahaha");
list.add(m1);
Map<String, String> m2 = new HashMap<>();
m2.put("fruits", "orange");
list.add(m2);
Map<String, String> m3 = new HashMap<>();
m3.put("fruits", "pear");
list.add(m3);
Map<String, HashSet<String>> mergeMap = new HashMap<>();
for(Map<String, String> map : list){
if(map == null){
continue;
}
for(Map.Entry entry : map.entrySet()){
mergeMap.computeIfAbsent((String)entry.getKey(), k -> genValue(k)).add((String)entry.getValue());
}
}
System.out.println(mergeMap.toString());
}
static HashSet<String> genValue(String str) {
return new HashSet<String>();
}
public static void main(String[] args) {
Test test= new Test();
test.testMergeMap();
}
}
这里重点记录一下computeIfAbsent, 这是1.8Map接口中新增的一个方法,作者的本意是将他作为本地缓存, 在1.8的HashMap ConcurrentHashMap中都可以看到他的身影, 方法签名如下:
public V computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction)
返回的值是你添加进去的元素的值。
此方法首先判断缓存map中是否存在指定的key值, 如果不存在会调用mappingFunction计算key的value,然后将key=value放入到缓存map中, java1.8会采用thread-safe的方式
从cache中存取记录. 1.8以前的putifAbsent也可以实现这种需求。 但是computeIfAbsent可以将一些逻辑或者限制条件写在mappingFunction里面。简单的如下:(以判断斐波那契数列为列)
import java.util.HashMap;
import java.util.Map;
public class Fibonacc {
static Map<Integer, Integer> cache = new HashMap<>();
static int cachefibonacc(int n){
return cache.computeIfAbsent(n, (value) -> {
System.out.println("cache " + n);
return cachefibonacc(n - 2) + cachefibonacc(n - 1);
});
}
public static void main(String[] args) {
cache.put(1, 1);
cachefibonacc(7);
}
}