I'm a little embarrassed to be asking this because I'm sure this is a very basic question but having searched and thought about it I still can't work this out.
The code is from a class the tutor walked through developing during a tutorial on collections for my course. The class represents a crime sheet of districts with associated crime codes. The sheet is implemented as a SortedMap where the keys are of type String (representing the district) and the values are an ArrayList of Integers (representing the crime codes).
There is one method that we didn't manage to finish during the tutorial that the tutor sent on a copy of and I can't follow the logic. The code for the method is below
/**
* displays districts affected by given crime code
*
* @param Integer crime code
* @return none
*/
public void displayAffectedDistricts(Integer crimeCode)
{
ArrayList<Integer> searchCode;
for(String eachDistrict: crimeTable.keySet())
{
searchCode = new ArrayList<Integer>();
searchCode.add(crimeCode);
if(!(searchCode.retainAll(crimeTable.get(eachDistrict))))
{
System.out.println("Code "+crimeCode+" found in district "+eachDistrict);
}
}
}
I've run the code and can see that this works but I can't follow the logic of the if condition.
My understanding is that searchCode.retainAll(crimeTable.get(eachDistrict)) will evaluate to the reference to the list searchCode and that, at that point, searchCode will contain the single value given by the crimeCode argument if the Map entry for eachDistrict has crimeCode in it's set of values or will otherwise be empty.
As far as I'm aware that's not a boolean value so can't be used as an if condition without a comparison operator.
Could someone please explain what I'm missing?
It's pretty bad code. But, here's how it works:
The retainAll() method returns true if the list changed because of the operation. A list is created that contains the target code, and if the other list contains it, the list will not change.
I would severely mark down the person who wrote this if I was marking it, because it's obtuse. Here's a better implementation, uses much less code, is straightforward and easy to understand and performs better too:
public void displayAffectedDistricts(Integer crimeCode) {
for (String eachDistrict : crimeTable.keySet()) {
if (crimeTable.get(eachDistrict).contains(crimeCode)) {
System.out.println("Code "+crimeCode+" found in district "+eachDistrict);
}
}
}
But even this can be improved upon, by using even less code and performs much better:
public void displayAffectedDistricts(Integer crimeCode) {
for (Map.Entry<String, ArrayList<Integer>> entry : crimeTable.entrySet()) {
if (entry.getValue().contains(crimeCode)) {
System.out.println("Code "+crimeCode+" found in district "+entry.getKey());
}
}
}
This last version avoids all the numerous calls to get(). It is the most elite way of coding it. Suggest this to your teacher, who by the way should find another job.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With