Create a dictionary in to be used in Android - java

I want to create a dictionary that maps two strings like so:
"package-name","game"
I know that this can be done using the following code:
HashMap<String, String> map = new HashMap<>();
map.put("app_package_name","game");
So in my application, I have a service that make changes depending on the application type as defined by its value. It seems like I cannot declare the map as a static global variable for the entire service class to use, which may means every time my service runs in the app to service the intent, the map will be recreated and new key-value pairs will be put again?
How should I do it if I want to just declare the map and put everything once, then when I handle the service intent, I just need to refer to the map object and double check its key? Is there a better way to do this?
P.S I would prefer to stick to dictionaries if possible.

As I understood - you need service to run all the time. But problem with services - they can be killed by system in any time. And if you store your map in such service it would be erased during service kill process. The simplest solution - use database. Preferably with Room framework with parallel put values and keys in map. On every read of map check if it's not null and not empty. If it is - populate it with data from database, else - use data from map. Don't try to write whole map while system trying to kill service - this would lead to unpredictable behaviour.

You can put your data in shared preferences and retrieve it when you would like, or serialize your obejct and save as JSON, and then work with it.

Related

How to cache data if there is no unique identifier?

I have a spring-boot application. I have a method that gives away some content. Let's say bank customers. Let's say that bank customers are not added to the database very often. How can I cache this method so that the method follows a new list to the database only when a new customer is added there?
Sounds trivial enough, but I can't think of a mechanism.
That is, we have a method of say
GET /customers
The cache is tuned to the unique parameters in the request. Since this method has no unique parameters, the data will always be returned from the cache, even if the list of clients is added one extra.
For example, you can think of some method with a boolean response. It would return true when the list is updated. But this looks like a nasty solution. And it also means that instead of one request you have to do two at once. And if you also have authorization, authentication - that's three requests. That sounds bad.
Can you give me a hint?
Where do you will store the cache? Some of them, like Redis, you can set the expiry of the cached data. So it will refresh the data for every time that you have set.
Or you can store something like 'version' in the database, and also add to cache. So everytime you add new customer, you also update the version. Then it can be used to compare the version in db and cache are same or not, if not then get new list to database and re-add to cache. But this way need to call db every time you hit the GET /customers.

Modifying the code based on user feedback

I am storing some data in a hash map. Now I want to modify the values associated with a key based on a user input and store them these way permanently.
To make myself more clear, I have a hashmap like this:
public static HashMap<String,Integer> mymap= new HashMap<String,Integer>();
mymap.put("Hi",2);
mymap.put("Hello",3);
I will take feedback from user in some user and if he wants then I will, say, store 4 against Hello. I want these changes to be saved for future references.
I have heard about Reflection API in Java, but am not sure whether that will serve the purpose.
Reflection API allows one to manipulate/access data that is not accessable otherwise - or some data on the class that is unknown at compile time.
In here, it is really not needed. All you need is to put() the element into the map, it will "remove" the old value from the key you just inserted (if it is already there) and associate it (the key) with the newly added value.
So, basically - all you need to do is myMap.put(key,newValue), and the implementation of the Map (assuming it is a correct one, of course) will take care of the rest.
If you want to store the data between runs of the program - you will have to save it (the map) on disk. In order to do so, you can use serialization, or if you can use Properties in some cases.
Make sure that you load the map from disk once the program starts, or you will not see the values you stored.
Just say, mymap.put(key,value);. It will update the value for matching key. If not there, it will insert a new entry e.g.
mymap.put("Hello",4);
If you don't want to insert new value for a new key e.g. World, you can put a check like this:
if(mymap.containsKey(key)){
mymap.put(key,value);
}else{
//no existing key found
}
The Preferences API makes it easy to store a small amount of data on disk. It's usually used to store configuration data. It's similar to the Windows registry.
Here's an introduction: http://docs.oracle.com/javase/1.4.2/docs/guide/lang/preferences.html

Static Cache on Android / Mobile Device for Efficiency

What is the best way to maintain a static cache on an Android device?
For example, say I have the look-up tables Type and Category - these two tables will rarely change....but if they do, they must be refreshed.
How can I store this data in some sort of cache on an Android device, while still updating them when something changes on the server? Seeing as they rarely change, I would like to minimize the amount of data being sent/received from the device.
Note - there are more look-up tables than this, I am just using two as an example.
Create A singleton instance of static HashTable/HashMap and store objects which contains data to populate screens ( Like primitive, pojo ,collections ect ) and a flag as well which will notify whether that value is being refreshed . set this value when you read any change from server . update with fresh value .

Is there a way to use Guava's HashBiMap with eviction?

I'm working with an enterprise level Java back end application and I need to build in token based user authentication. The front end utilizes PHP and communicates with the Java back end via SOAP.
I thought about using Guava's HashBiMap to help me with the problem. It would be useful to me because I could generate UUID tokens as the keys and store User objects as the values in a static HashBiMap. When a User first successfully logs in, the User will be added to the HashBiMap and the login response will return the generated UUID token. Subsequent SOAP requests for the same user will be made using the token only.
The problem I'm facing now is I need some sort of eviction logic that would allow these tokens to be evicted after 30 minutes of inactivity. In my research it appears that the HashBiMap does not natively support eviction like Guava's MapMaker does.
Does anyone have any recommendations on how I could use the HashBiMap and support eviction for inactivity? If this approach is not ideal, I'm open to other strategies.
Update:
I think I need to use a HashBiMap because I want to be able to lookup a User object in the map and get their already existing token if the User is still in the map. For example, if a User closes their browser within the 30 minute window and a few minutes later returns and logs back in again, I need to check to see if the User already exists in the map so I can return their existing token (since it technically is still valid).
The simplest answer is that no, you can't have a HashBiMap with automatic eviction. The maps that MapMaker makes are specialized concurrent maps. HashBiMap is basically just a wrapper around two HashMaps.
One option might be to store the UUID to User mapping in a MapMaker-created map with eviction and store the User to UUID mapping in another MapMaker-created map that has weak keys. When the entry in the map with eviction is evicted, the entry in the inverse map should be invalidated soon because of the UUID weak reference being cleared (assuming no references to the UUID are held elsewhere). Even if that mapping were still there when the user goes to log in again, when you look up the UUID in the map with eviction and discover no entry for it, you know you need to generate a new UUID and create new mappings.
Of course, you probably need to consider any potential concurrency issues when doing all this.
To echo #ColinD's answer, HashBiMap is a non-lazy map wrapper; as such, you're not going to automatically see changes from the MapMaker map reflected in the BiMap.
All is not lost, though. #ColinD suggested using two maps. To take this a step further, why not wrap these two maps in a custom BiMap implementation that is view-based rather than copying the source map (as HashBiMap does). This would give you the expressive API from BiMap with the custom functionality that you require.

Google App Engine + Memcache how to get all data from cache

Inside my system I have data with a short lenght of life, it means that the data is still actuall not for a long time but shold be persisted in data store.
Also this data may be changed frequently for each user, for instance each minute.
Potentially amount of users maybe large enough and I want to speed up the put/get process of this data by usage of memcache and delayed persist to the bigtable.
No problems just to put/get objects by keys. But for some use cases I need to retrieve all data from cache that still alive but api allows me to get data only by keys. Hence I need to have some key holder that knows all keys of the data inside memcache... But any object may be evicted and I need to remove this key from global registry of keys (but such listener doesn't work in GAE). To store all this objects in the list a map is not accaptable for my solution because each object should has it's own time to evict...
Could somebody recommend me in which way I should move?
It sounds like what you really are attempting to do is have some sort of queue for data that you will be persisting. Memcache is not a good choice for this since as you've said, it is not reliable (nor is it meant to be). Perhaps you would be better off using Task Queues?
Memcache isn't designed for exhaustive access, and if you need it, you're probably using it the wrong way. Memcache is a sharded hashtable, and as such really isn't designed to be enumerated.
It's not clear from your description exactly what you're trying to do, but it sounds like at the least you need to restructure your data so you're aware of the expected keys at the time you want to write it to the datastore.
Since I am encountering the very same problem, which I might solve by building a decorator function and wrap the evicting function around it so that key to the entity is automatically deleted from key directory/placeholder on memcache, i.e. when you call for eviction.
Something like this:
def decorate_evict_decorator(key_prefix):
def evict_decorator(evict):
def wrapper(self,entity_name_or_id):#use self if the function is bound to a class.
mem=memcache.Client()
placeholder=mem.get("placeholder")#could use gets with cas
#{"placeholder":{key_prefix+"|"+entity_name:key_or_id}}
evict(self,entity_name_or_id)
del placeholder[key_prefix+"|"+entity_name]
mem.set("placeholder",placeholder)
return wrapper
return evict_decorator
class car(db.Model):
car_model=db.StringProperty(required=True)
company=db.StringProperty(required=True)
color=db.StringProperty(required=True)
engine=db.StringProperty()
#classmethod
#decorate_evict_decorator("car")
evict(car_model):
#delete process
class engine(db.Model):
model=db.StringProperty(required=True)
cylinders=db.IntegerProperty(required=True)
litres=db.FloatProperty(required=True)
manufacturer=db.StringProperty(required=True)
#classmethod
#decorate_evict_decorator("engine")
evict(engine_model):
#delete process
You could improve on this according to your data structure and flow. And for more on decorators.
You might want to add a cron to keep your datastore in sync the memcache at a regular interval.

Categories

Resources