Introduction:

Recently, I was working on a project, which was originally written by C++, but now needs to be translated into Java. In the process of translation, my colleague did not understand the specific requirements clearly, so he translated it into English in the development, until there was a failure in production (the test did not detect it?). It took research together to discover…

demand

Let’s take a look at the C++ code

    //vector<CorBillGroup>& vCorBillGroups 
	while(rs->next()){
		if(load(rs,bill)){
			// Determine the grouping
			corId = pm->getCorpId(bill.getPartyRoleId(),bill.getBillingCycleId());
			if (corId < 0)
				throw BusinessLogicException("Unable to find bank deduction block ID", corId);
			int i=0;
			for ( i=0; i<vCorBillGroups.size(); i++) {if(vCorBillGroups[i].getCorperationId() == corId){
					 vCorBillGroups[i].add(bill);
					 break; }}if(i == vCorBillGroups.size()) { CorBillGroup corBillGroup; corBillGroup.setCorperationId(corId); corBillGroup.add(bill); vCorBillGroups.push_back(corBillGroup); }}}Copy the code

Then take a look at the first version of a colleague’s translation

 for (VirtualBillVO vo : bills) {
            long partyRoleId = vo.getPartyRoleId();
            Partner partner = getPartnerManager().getPartner(Integer.parseInt(partyRoleId + ""));
            corId = partner.getCorpId();

            if (corId < 0) {
                throw new BusinessLogicException("Unable to find bank deduction block ID", corId);
            }
            int i = 0;
            for (CorBillGroupVO corVo : vCorBillGroups) {
                i++;
                if (corVo.getM_iCorperationId() == corId) {
                    corVo.add(vo);
                    break; }}if (i == vCorBillGroups.size()) {
                CorBillGroupVO corBillGroup = newCorBillGroupVO(); corBillGroup.setM_iCorperationId(corId); corBillGroup.add(vo); vCorBillGroups.add(corBillGroup); }}Copy the code

Analysis of the

Regardless of what’s going on here, from a purely structural point of view, there seems to be nothing wrong with the code. But programs don’t look at code structure! Since the C++ code has specific business implications, a little background on this code: you take a set of bills, group them by corId, and return them. Such a simple requirement, and not knowing why the C++ code was written so complex, also caused confusion among colleagues who translated the code.

  • C++ : If there is a corId in the group, add the bill to the ith element of vCorBillGroups, and jump out of the loop to judge whether the length of I and vCorBillGroups is equal. (loop vcorbillgroups.size () times, each time I ++, then I must be equal to vcorbillgroups.size () when the loop ends. I must be smaller than vcorbillgroups.size (); If there is no break in the preceding loop, the corId is not in an existing group and is added to vCorBillGroups.
  • Java: I++ is used before the break condition is satisfied, so it is normal when there is no break, but different when there is break, such as vcorbillgroups.size () = 1, I == vcorbillgroups.size (); vcorbillgroups.size (); The grouping is added again, so it doesn’t mean the same as the C++ code.
  • What’s the difference? If you look closely, the difference is the use of i++, for(;; Foreach = foreach = foreach = foreach = foreach = foreach = foreach = foreach = foreach = foreach = foreach = foreach = foreach = foreach = foreach = foreach = foreach = foreach = foreach = foreach = foreach = foreach = foreach = foreach = foreach

To solve

The simplest solution is to put i++ after the break condition, as in the above analysis, but does grouping code really need to be so obscure? Different people…

conclusion

Few people really pay attention to the order in which the conditions for the loop are executed, and the difference between I ++ and ++ I. My boss hesitated a bit when he saw this code, and then he wondered if the I ++ was executed after the break. Normally this kind of code might be fine, but once certain boundary conditions are triggered, it may not be what you expect. So before writing code, it is important to know exactly what you want to implement. If a colleague knew it was a block of code at the beginning of the translation, I believe he would never write it like this!