Consider the code below
private static boolean noHashClash(JSONArray ja,String hash,long epoch,long stay) { int i,diff,len = ja.length(); String oHash; JSONObject pjo; try { for(i=0;i < len;i++) { pjo = ja.optJSONObject(i); oHash = pjo.optString("hash",""); if ((null == pjo) || (0 == oHash.length())) continue; diff = TLSH.totalDiff(hash,oHash,false); if (Geo.hashBlur > diff) { pjo.accumulate("ats",epoch); pjo.accumulate("stays",stay); int times = pjo.optInt("times",0); pjo.put("times",times + 1); return false; } } return true; } catch(Exception e) { Feedback.recordError(Utils.errorString(e)); return true; } }
What I am doing here is comparing a hash value with the hashes of objects in the JSONArray. If a hash “match” (fuzzy) is found the function returns false
. Prior to doing so it modifies the object which matched – the lines
pjo.accumulate("ats",epoch); .... pjo.put("times",times + 1);
Whist this compiles and runs correctly, when I save and then retrieve that JSONArray I find that the changes have not stuck. My understanding is that Java passes function parameters by value where the “value” for object parameters is the actual object itself.
This implies that any changes I make to object attributes inside a function should stick and that does indeed happen. Why then are nested objects apparently being treated differently here. I suspect there is a gap here in my understanding of how such things work in Java.
Advertisement
Answer
The heart of the problem here is the fact that I am modifying a local reference to the nested object.
pjo = ja[i] ..... ..... pjo.accumulate(...
For these changes to become part of the passed JSONArray parameter you have to also do
ja[i] = pjo;
without which the changes are lost once the routine is exited. Java appears to have its own peculiar way of handling object parameters which is not obvious – at least not to me with my background in Delphi, C and PHP.