My Java program makes a request to client's API and client's API will return a key-value pair on irregular time intervals (i.e. not every 5 seconds / 10 seconds, sometimes 1 second or 5 seconds).
And I have inserted my own code which is a HashMap
, into the client API code to store all the key-value pairs.
My goal is run the below code marked with "!!!" as soon as the Hashmap conditions are matched.
I am not an expert in Java data synchronization. Note that Thread.Sleep(3000)
would not work, as the key-value pairs are updated on irregular time intervals. Moreover, the value of the same key will also change over time.
I tried the run the program below and it immediately ran through the block of code marked with "!!!", which is not what I want to achieve.
What is the most efficient solution to tackle this problem ?
Class Testing{
public static void main(String[] args){
// connect to API...
ClientAPI clientAPI = new ClientAPI();
clientAPI.connect();
// make a request to retrieve an update of a HashMap
clientAPI.requestHashMapUpdate();
// !!! execute the following block of code only if hashmap contains a specific key value pair, i.e. key1, 1
// if hashmap does not contain key or the key-value pair do not match , then wait until the key-value pair are matched and run the code
if(clientAPI.getMyHashMap().containsKey("key1")){
if(clientAPI.getMyHashMap().get("key1") == 1){
System.out.println("Print Me only if key and value are matched !!!!!!!!");
}
}
}
}
Class ClientAPI{
private HashMap<String,Integer> myHashMap;
// Constructor
public clientAPI(){
myHashMap = new HashMap<String,Integer>();
}
// callback function of API's requestHashMapUpdate method
public void updateHashMapKeyValuePair(String key, int value){
System.out.println("Key:" + key + ", Value: " + value);
// code i wrote to update hashmap with key value pair returned from API
myHashMap.put(key,value);
}
// my code to retrieve the latest snapshot of myHashMap
public HashMap<String,Integer> getMyHashMap(){
return myHashMap;
}
}
Override your client API (if it is not closed to extends):
class MyClientAPI extends ClientAPI {
...
@Override
public void updateHashMapKeyValuePair(String key, int value) {
super.updateHashMapKeyValuePair(key, value);
if("key1".equals(key) && 1 == value)
System.out.println("Print Me only if key and value are matched !!!!!!!!");
}
...
}
and simply check each new value that comes in.
To use it, only change
ClientAPI clientAPI = new MyClientAPI();
Another way to solve this is to provide your ClientAPI
class with the ability to register listeners
interface UpdateHashMapKeyValuePairListener {
void digestUpdate(String key, int value);
}
class ClientAPI {
...
private List<UpdateHashMapKeyValuePairListener> listeners = new ArrayList();
...
public void registerUpdateListener(UpdateHashMapKeyValuePairListener u) {
listeners.add(u);
}
...
public void updateHashMapKeyValuePair(final String key, final int value) {
listeners.forEach(u -> u.digestUpdate(key, value));
...
}
...
}
then, anyone who wants to know when a new value enters, just implement this interface, e.g.
...
clientAPI.registerUpdateListener((key, value) -> {
if("key1".equals(key) && 1 == value)
System.out.println("Print Me only if key and value are matched !!!!!!!!");
});
clientAPI.connect();
...