Modifying the code based on user feedback - java

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

Related

Create a dictionary in to be used in Android

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.

How can I avoid growing my hashmaps to 2 keys until I try to add a second key?

I have a situation where I have tons of hashmaps (millions and millions) in my server, and 95% of them have literally only one key, ever.
The server runs out of memory; which probably may have something to do with the fact that initial HashMap default size is 16, so for every HashMap object I'm wasting a ton of memory.
Short of re-designing the server with a new data structure that flexibly stores the data as 1 element OR an entire hashmap (which I'd prefer avoiding), I'm trying to first optimize this by changing the initial size to 1:
Map<String, Type2> myMiniMap = new HashMap<>(1);
However, my concern is that due to default load factor of 0.75 in HashMaps, this would immediately get increased to 2 the moment I add the first key to the map (since 1*0.75 < 1, which is how I understand hash sizing logic in Java)
Assuming my understanding above is correct (that by default, Java will create a space for 2 keys as soon as I add the first key to the hash), is there a way to prevent this from happening till I actually try to insert the second key?
E.g., should I set loadFactor to zero or one?
If they're truly only ever going to be singletons, why not use Collections.singletonMap to create them? The downside of this is that the map that is created is immutable.
Alternatively, you could create your own class implementing Map that will store a key and value in class fields and then, if an attempt is made to add a second key value, it will switch to using a HashMap as its default backing store. It would be more tedious than difficult to accomplish.

get last update Date of hashmap entries

I want to access the last update time of entries inside a hashmap. i'm wondering if java can provide me with this information or i need to store them somewhere and retrieve them.
You will need to store them somewhere extra.
Or you can create your custom map implementation which would either extend Java's hashmap or use an hashmap internally and would additionally remember the last date of any action performed on your dataset, you seek to remember.
This would have the advantage that it would be ubiquitous and you wouldn't need to care about it within your algorithm, which uses the hashmap

How can I add more than one database record to my HashMap?

I have a HashMap that I am using to store information from my database. I have a Result Set that reads from each column of the database, and the Result Set is used to initialize a few string variables. These strings are then used in the HashMap. For example, one of my lines of code for my HashMap is parameters.put("CertificateCode", CertificateCode);. From what I'm beginning to understand, the first parameter of the HashMap allows the application to know WHERE to put the information, and the second parameter tells the HashMap WHAT information to put in.
Here is my problem... I noticed that if I try to run a loop through these lines of code, it will simply replace an existing value in the HashMap with the new one, thus only displaying the last record from my database.
How would I go about making the HashMap allow for the storage of multiple database records? I need this to work in a way that would still allow me to pass the parameters in to my Jasper Report. This method is JasperPrint jasperPrint = JasperFillManager.fillReport(), and it requires the parameters of JasperReport, Map<String, Object>, and a Connection.
I thought it might work if I added an array list to the HashMap. However, the "fillReport" method will not accept this as a proper parameter.
Any help would be much appreciated! I have been fighting with this reporting library for way too long now.
Thank you.
HashMap wont allow duplicate keys, when you try to insert value for a key which is already present inside the map then it will overwrite the key value with the new one.
If you want a map with duplicate keys then you have to go for Guava's Multimap.

java efficient de-duplication

Lets say you have a large text file. Each row contains an email id and some other information (say some product-id). Assume there are millions of rows in the file. You have to load this data in a database. How would you efficiently de-dup data (i.e. eliminate duplicates)?
Insane number of rows
Use Map&Reduce framework (e.g. Hadoop). This is a full-blown distributed computing so it's an overkill unless you have TBs of data though. ( j/k :) )
Unable to fit all rows in memory
Even the result won't fit : Use merge sort, persisting intermediate data to disk. As you merge, you can discard duplicates (probably this sample helps). This can be multi-threaded if you want.
The results will fit : Instead of reading everything in-memory and then put it in a HashSet (see below), you can use a line iterator or something and keep adding to this HashSet. You can use ConcurrentHashMap and use more than one thread to read files and add to this Map. Another multi-threaded option is to use ConcurrentSkipListSet. In this case, you will implement compareTo() instead of equals()/hashCode() (compareTo()==0 means duplicate) and keep adding to this SortedSet.
Fits in memory
Design an object that holds your data, implement a good equals()/hashCode() method and put them all in a HashSet.
Or use the methods given above (you probably don't want to persist to disk though).
Oh and if I were you, I will put the unique constraint on the DB anyways...
I will start with the obvious answer. Make a hashmap and put the email id in as the key and the rest of the information in to the value (or make an object to hold all the information). When you get to a new line, check to see if the key exists, if it does move to the next line. At the end write out all your SQL statements using the HashMap. I do agree with eqbridges that memory constraints will be important if you have a "gazillion" rows.
You have two options,
do it in Java: you could put together something like a HashSet for testing - adding an email id for each item that comes in if it doesnt exist in the set.
do it in the database: put a unique constraint on the table, such that dups will not be added to the table. An added bonus to this is that you can repeat the process and remove dups from previous runs.
Take a look at Duke (https://github.com/larsga/Duke) a fast dedupe and record linkage engine written in java. It uses Lucene to index and reduce the number of comparison (to avoid the unacceptable Cartesian product comparison). It supports the most common algorithm (edit distance, jaro winkler, etc) and it is extremely extensible and configurable.
Can you not index the table by email and product ID? Then reading by index should make duplicates of either email or email+prodId readily identified via sequential reads and simply matching the previous record.
Your problem can be solve with a Extract, transform, load (ETL) approach:
You load your data in an import schema;
Do every transformation you like on the data;
Then load it into the target database schema.
You can do this manually or use an ETL tool.

Categories

Resources