今天做一个在项目遇到一个小小的难题,大概想了半个小时,突然灵光一闪而过,突然发现Map就可以实现这个功能;
业务需求如下:
根据不同经销商求出有多少合同,每一条合同对应多个返利政策,
第一步:把一条合同返利金额求出,
第二步:在当前这个经销商金额汇总,
第三步:每一个经销商形成一条数据,保存到另外一张表中
实现结果如下:
第一步:把数据装载到Map中
//定义一个Map集合,value存放的是一个对象
Map<String, VRebateGenerate> resultMap = new HashMap<String, VRebateGenerate>();
for (VRebateGenerate vRebateGenerates : vRebateGenerate) {
if (resultMap.get(vRebateGenerates.getDbCode()) != null ) {
VRebateGenerate rete = resultMap.get(vRebateGenerates.getDbCode());
// 销售台阶返利金额+等级返利金额
BigDecimal amt = MathUtil.add(vRebateGenerates.getXsPracticalRebateAmt(), vRebateGenerates.getDjPracticalRebateAmt());
BigDecimal proveAmt = rete.getAmt();
rete.setAmt(MathUtil.add(amt,proveAmt));
resultMap.put(vRebateGenerates.getDbCode(), rete);
}else{
// 销售台阶返利金额+等级返利金额
BigDecimal amt = MathUtil.add(vRebateGenerates.getXsPracticalRebateAmt(), vRebateGenerates.getDjPracticalRebateAmt());
vRebateGenerates.setAmt(amt);
resultMap.put(vRebateGenerates.getDbCode(),vRebateGenerates);
}
第二步:遍历Map集合,插入相关数据
for (Map.Entry<String, VRebateGenerate> entry : resultMap.entrySet()) {
System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
VRebateGenerate amt = entry.getValue();
// 生成结算金额列表
Eval eval = new Eval();
eval.setDbCode(entry.getKey());
eval.setCorp(SecUtil.getCurrentCorpCode());
eval.setEvalYy(amt.getEvalYy());//年份
eval.setEvalMm(amt.getEvalMm());//月份
eval.setEvalAmt(amt.getAmt());
eval.setCreatedAt(DateToUtils.getDateTime());
eval.setCreatedBy(SecUtil.getCurrentUserCode());
evalMapper.insert(eval);
}
项目总结
Map :存储的是键值对,一对一对出现的,要保证键的唯一性.
我每次遍历都会根据相同的经销商汇总,然后在遍历经销商。
Map总结
Map集合的key和value都可以是任何引用类型的数据。Map集合的key不允许重复,value允许重复。key和value之间存在单向一对一关系,即通过指定的键可以找到唯一,确定的value。Map集合中获取数据时,只要给出指定的key,就可以取出对应的value。
Map接口中定义的常用方法:
(1)void clear():删除该Map对象中所有的键值对。
(2)boolean containsKey(Object key):查询Map中是否包含指定key。
(3)boolean containsValue(Object value):查询Map中是否包含一个或多个value。
(4)Set entrySet():返回Map中所包含的键值对所组成的Set集合,每个集合元素都是Map.Entry对象。
(5)Object get(Object obj):返回指定key所对应的value。如果没有,这返回null。
(6)boolean isEmpty():查询该Map是否为空,如果为空则返回true。
(7)Set keySet():返回该Map中所有key组成的Set集合。
(8)Object put(Object key, Object value):添加一个键值对,如果当前Map中已经有一个与该key相等的键值对,则新的键值对将覆盖原来的键值对。
(9)void putAll(Map m):将指定Map中的键值对复制到m中。
(10)Object remove(Object key):删除指定key所对应的键值对,如果不存在,则返回null。
(11)int size():返回Map里的键值对个数。
(12)Collection values():返回该Map里所有的vlaue组成的Collection。
Map中包括一个内部类Entry。该类封装了一个键值对。
Entry包含的三个方法:
(1)Object getKey():返回该Entry里包含的key值。
(2)Object getValue():返回该Entry里包含的value值。
(3)Object setValue(V value):设置该Entry里包含的value值,并返回新设置的value值。
HashMap和Hashtable实现类
HashMap和Hashtable都是Map接口的典型实现类,Hashtable是一个古老的集合,JDK1.0起就出现了。
HashMap和Hashtable的典型区别:
(1)Hashtable是一个线程安全的Map实现,但HashMap是线程不安全的实现。所以HashMap比Hashtable的性能高一点。
(2)Hashtable不允许使用null作为key和value。
注意:HashMap和Hashtable判断两个key相等的标准是:两个key通过equals方法比较返回true,两个key的hashCode值也要相等。
HashMap和Hashtable包含一个containsValue方法用于判断是否包含指定vlaue,HashMap和Hashtable判断值相等的标准:只要两个对象通过equals方法比较返回true即可。
LinkedHashMap类:
LinkedHashMap和LinkedHashSet一样,也是使用双向链表来维持键值对的顺序,该链表定义了迭代顺序,该迭代顺序与键值对的插入顺序保持一致。
LinkedHashMap需要维护元素的插入顺序,因此性能略低于HashMap的性能,但在迭代方法Map集合的全部元素时将有很好的性能,因为它以链表来维护内部顺序。
Properties类
Properties类是Hashtable的子类。该对象在处理属性文件时特别方便。Properties类可以把Map对象和属性文件关联起来,从而可以把Map对象中的键值对写入属性文件,也可以把属性文件中的属性名=属性值加载到Map对象中。由于属性文件中的属性名和属性值只能是字符串类型,所以Properties里的key和value都是字符串类型。Properties提供的常用方法:
(1)String getProperty(String key):获取Properties中指定属性名对应的属性值,类似于Map的get方法。
(2)String getProperty(String key, String defaultValue):该方法与上面的方法基本类似,如果Properties中不存在指定的key值,该方法返回默认值。
(3)Object setProperty(String key,String value):设置属性值,类似Hashtable的put方法。
(4)void load(InputStream inStream):从属性文件(以输入流表示)中加载属性名=属性值,把加载到的属性名=属性值对追加到Properties里。
(5)void store(OutputStream out,String comments):将Properties中的键值对写入指定属性文件(以输出流表示)。
经典实例: