/* This class is an extension (aka "child" or "subclass") of the KeyValPair ** class. Its instances have, in addition to the 'key' and 'value' components ** inherited from its parent, two new components, the purposes of which are ** to store the number of times that the 'key' and 'value' components, ** respectively, were accessed as a result of calls to the getKey() and ** getValue() methods. Two new observer methods allow clients to access ** those counts. ** ** Authors: P.M.J. and R.W.M ** last modified: 12/06/2025 */ public class KeyValPairWithCounts extends KeyValPair { // instance variables (fields/attributes) // -------------------------------------- private int keyAccessCount = 0; // # times this object's key was accessed private int valueAccessCount = 0; // # times this object's value was accessed // constructors // ------------ /* Initializes this KeyValPairWithCounts object to have the given ** strings as its key and value components and to have zero as the ** value of each of its two access count components. */ public KeyValPairWithCounts(String key, String value) { setTo(key,0,value,0); } /* Initializes this KeyValPairWithCounts object to be that ** described by the given string, which is expected to be in ** the format ** ** key : value [ : keyAccessCount : valueAccessCount ] ** ** where the square brackets indicate an optional part. ** If the two access count values are missing, they are taken ** to be zero. ** */ public KeyValPairWithCounts(String fromString) { setTo("",0,"",0); //Set default values //Separate the string into its four (or two) parts int index = fromString.indexOf(DELIMITER); if (index != -1) { this.key = fromString.substring(0,index).trim(); String rest = fromString.substring((index+DELIMITER.length())).trim(); //Determine if access counts are present index = rest.indexOf(DELIMITER); if (index == -1) { this.value = rest; } else { // Access and value counts should be present this.value = rest.substring(0,index); rest = rest.substring((index+DELIMITER.length())).trim(); //Isolate the two counts index = rest.indexOf(DELIMITER); if(index > 0) { String accessCount = rest.substring(0,index); String valueCount = rest.substring((index+DELIMITER.length())); this.keyAccessCount = Integer.parseInt(accessCount); this.valueAccessCount = Integer.parseInt(valueCount); } } } } // observers // --------- /* Returns the key component of this object ** and increments its key access count. */ @Override public String getKey() { keyAccessCount = keyAccessCount + 1; return super.getKey(); } /* Returns the value component of this object ** and increments its value access count. */ @Override public String getValue() { valueAccessCount = valueAccessCount + 1; return super.getValue(); } /* Returns the number of times that getKey() was invoked ** upon this KeyValPairWithCounts object. */ public int getKeyAccessCount() { return this.keyAccessCount; } /* Returns the number of times that getValue() was invoked ** upon this KeyValPairWithCounts object. */ public int getValueAccessCount() { return this.valueAccessCount; } /* Returns a string of the following form that represents the current ** state and value of this object: ** ** key : value : keyAccessCount : valueAccessCount */ @Override public String toString() { return //key + DELIMITER + value super.toString() + DELIMITER + keyAccessCount + DELIMITER + valueAccessCount; } // mutators // -------- /* Resets the key access count to zero. */ public void resetKeyAccessCount() { this.keyAccessCount = 0; } /* Resets the value access count to zero. */ public void resetValueAccessCount() { this.valueAccessCount = 0; } // private mutator // --------------- /* Sets the four components of this object to be the ** values of the parameters. */ private void setTo(String key, int keyAccessCount, String value, int valueAccessCount) { super.setTo(key, value); // Use parent class's setTo() method this.keyAccessCount = keyAccessCount; this.valueAccessCount = valueAccessCount; } }