周五呢,有个新的需求变更,具体描述如下:
因为是调用接口得到的数据,是一种明细数据,比如有字段疫苗产品,疫苗批号,药监码,数量,单价,
这样的话在画面显示的数据就是有很多因为药监码不同,但是其它信息相同的数据都是一条一条的记录,现在要做的是不用管药监码这个值,只要产品及批号相同,那么该产品的数量和单价各自累计求和,只显示一条数据即可,目前显示如下图所示:
需求变更以后的显示效果图如下:
如果说数据时在数据库中,那么我直接根据产品名称和批号进行分组,,对数量和金额进行sum就可以了,但是因为是掉接口过来的数据,那么我只能在JAVA代码里面进行处理。
我的第一反应是采用java 8中流的技术来解决这个问题,可是我们还是java 7,所以不可以使用流,只能在代码中采用循环的方式进行解决,数据合并。我先说一下,我犯的错误:
BigDecimal bigDecimal1 = new BigDecimal("5");
bigDecimal1.add(new BigDecimal("6"));
System.out.println(bigDecimal1);
基本和上面代码类似,我的数据已经进行了合并,但是数量和金额总是不是累加之后的值!!!
打断点,走了一下,发现bigDecimal.add(new BigDecimal("6"))
之后,bigDecimal1
的值还是5
,于是去看了一下BigDecimal
中的add
方法源码:
/**
* Returns a {@code BigDecimal} whose value is {@code (this +
* augend)}, and whose scale is {@code max(this.scale(),
* augend.scale())}.
*
* @param augend value to be added to this {@code BigDecimal}.
* @return {@code this + augend}
*/
public BigDecimal add(BigDecimal augend) {
if (this.intCompact != INFLATED) {
if ((augend.intCompact != INFLATED)) {
return add(this.intCompact, this.scale, augend.intCompact, augend.scale);
} else {
return add(this.intCompact, this.scale, augend.intVal, augend.scale);
}
} else {
if ((augend.intCompact != INFLATED)) {
return add(augend.intCompact, augend.scale, this.intVal, this.scale);
} else {
return add(this.intVal, this.scale, augend.intVal, augend.scale);
}
}
}
从源码中可以看出,当你调用add
方法的时候,返回了一个BigDecimal
类型的值,这个值是this
当前对象(在我这里也就是bigDecimal1
的值)加上参数中BigDecimal
类型的值得和,返回的是一个BigDecimal
类型的值,我错误的以为bigDecimal1
是相加后返回的值,所以导致累加的结果一直没有变化。
测试代码:
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class BigDecimalTest {
public static void main(String[] args) {
DisplayInfo info1 = new DisplayInfo();
info1.setYmcp("A");
info1.setPh("001");
info1.setPrice("10");
info1.setSl("1");
DisplayInfo info2 = new DisplayInfo();
info2.setYmcp("A");
info2.setPh("001");
info2.setPrice("10");
info2.setSl("1");
DisplayInfo info3 = new DisplayInfo();
info3.setYmcp("A");
info3.setPh("001");
info3.setPrice("10");
info3.setSl("1");
DisplayInfo info4 = new DisplayInfo();
info4.setYmcp("A");
info4.setPh("001");
info4.setPrice("10");
info4.setSl("1");
DisplayInfo info5 = new DisplayInfo();
info5.setYmcp("B");
info5.setPh("002");
info5.setPrice("10");
info5.setSl("1");
DisplayInfo info6 = new DisplayInfo();
info6.setYmcp("B");
info6.setPh("002");
info6.setPrice("10");
info6.setSl("1");
List<DisplayInfo> list = new ArrayList<>();
list.add(info1);
list.add(info2);list.add(info3);list.add(info4);list.add(info5);list.add(info6);
System.out.println("合并前的记录 :");
for (DisplayInfo vo:list){
System.out.println("产品: " +vo.getYmcp() + " 批号: " + vo.getPh() + " 数量 : " + vo.getSl() + "金额: " +vo.getPrice());
}
List<DisplayInfo> newList = mergeData(list);
System.out.println("合并后的记录 :");
for (DisplayInfo vo:newList){
System.out.println("产品: " +vo.getYmcp() + " 批号: " + vo.getPh() + " 数量 : " + vo.getSl() + "金额: " +vo.getPrice());
}
}
private static List<DisplayInfo> mergeData(List<DisplayInfo> result) {
List<DisplayInfo> list = new ArrayList<>();
//map存放result中的产品简称和批号 map的大小即是显示的数据条数
Map<String,String> map = new HashMap<String, String>();
for (DisplayInfo vo:result){
if (!map.containsKey(vo.getYmcp()) && !map.containsValue(vo.getPh())){
map.put(vo.getYmcp(),vo.getPh());
}
}
if (map!=null && !map.isEmpty()){
DisplayInfo bo = null;
for (Map.Entry<String, String> entry : map.entrySet()) {
//map中的已经是去重的疫苗产品和批号
bo = new DisplayInfo();
bo.setYmcp(entry.getKey());
bo.setPh(entry.getValue());
//循环调用webservice的结果集进行其他信息填充,并对数量和单价进行累加 药监码不用显示
for(DisplayInfo rsVo:result){
if (bo.getYmcp().equals(rsVo.getYmcp()) && bo.getPh().equals(rsVo.getPh())){
if (bo.getSl() != null){
if (rsVo.getSl()!=null){
bo.setSl(new BigDecimal(bo.getSl()).add(new BigDecimal(rsVo.getSl())).toString());
}
}else{
bo.setSl(rsVo.getSl());
}
if (bo.getPrice() != null){
if (rsVo.getPrice()!=null){
bo.setPrice(new BigDecimal(bo.getPrice()).add(new BigDecimal(rsVo.getPrice())).toString());
}
}else{
bo.setPrice(rsVo.getPrice());
}
}
}
list.add(bo);
}
}
return list;
}
}
class DisplayInfo{
private String ymcp;
private String ph;
private String price;
private String sl;
public String getYmcp() {
return ymcp;
}
public void setYmcp(String ymcp) {
this.ymcp = ymcp;
}
public String getPh() {
return ph;
}
public void setPh(String ph) {
this.ph = ph;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public String getSl() {
return sl;
}
public void setSl(String sl) {
this.sl = sl;
}
}
运行结果:
合并前的记录 :
产品: A 批号: 001 数量 : 1金额: 10
产品: A 批号: 001 数量 : 1金额: 10
产品: A 批号: 001 数量 : 1金额: 10
产品: A 批号: 001 数量 : 1金额: 10
产品: B 批号: 002 数量 : 1金额: 10
产品: B 批号: 002 数量 : 1金额: 10
合并后的记录 :
产品: A 批号: 001 数量 : 4金额: 40
产品: B 批号: 002 数量 : 2金额: 20