Multi Layered Hashmap and Arraylist - java

I was working on a java program that takes a string and splits it into different levels.
Map<String, ArrayList<Map<String, ArrayList<Map<String,Map<String, String>>>>>> courseInfoMap = new HashMap<String, ArrayList<Map<String,ArrayList<Map<String,Map<String, String>>>>>>();
ArrayList<Map<String, ArrayList<Map<String,Map<String, String>>>>> courseNumList = new ArrayList<Map<String, ArrayList<Map<String,Map<String, String>>>>>();
Map<String, ArrayList<Map<String,Map<String, String>>>> courseNumTextbookMap = new HashMap<String, ArrayList<Map<String,Map<String, String>>>>();
ArrayList<Map<String,Map<String, String>>> listOfTextbooks = new ArrayList<Map<String,Map<String,String>>>();
Map<String, Map<String, String>> textbookMap = new HashMap<String, Map<String, String>>();
Map<String, String> isbnMap = new HashMap<String,String>();
Essentially,
I'm trying to have a course code --> list of course num --> course num (key) --> list of textbooks --> textbook --> isbn number(str) --> price
So because some course codes have multiple course numbers it points to an arraylist.
I have been adding stuff backwards, so loops within loops. Assuming I did not screw up there. I've been trying to loop through the elements in the same sort of way assuming they were probably added.
for(Map.Entry<String, ArrayList<Map<String, ArrayList<Map<String,Map<String, String>>>>>> entry : courseInfoMap.entrySet()){
System.out.println(entry.getKey());// COURSE CODE
for(int i = 0; i < entry.getValue().size();i++){//loops through arraylist of course numbers
System.out.println("i("+i+" - " + entry.getValue().get(i));
for(Map.Entry<String, ArrayList<Map<String,Map<String,String>>>> entry2 : entry.getValue().get(i).entrySet()){
System.out.println(" " + entry2.getKey());
// . . . and so on
This hasnt worked it just loops through everything. On each level.
My question is how do I navigate through a large number of hashmaps and/or is there a better way to do this.
Example:
AAAA
100
Name
###
$$$
Name
### <-- different from past
$$$
200
Name
###
$$$
BBBB
101
Name
###
$$$

This seems exceedingly complicated, and frankly if I had to maintain that I'd really not look forward to it. Off the top of my head there are several other approaches you could probably take...
Use a relational database
Either an in-memory database or something like mysql or postgresql. They are designed for this sort of thing - organizing data and allowing for ad-hoc queries.
Put your data in Objects
Instead of Maps and Lists, just create an object that defines most of it in one place. Store that object in the List or Map and search for what you need directly. If you don't have too much data, a brute-force uninindexed search probably won't be that bad in wall-clock time.

Related

Writing/appending data to a CSV file, column wise, in JAVA

I want to write/append data to a CSV file, column-by-column, in below fashion:
query1 query2 query3
data_item1 data_item7 data_item12
data_item2 data_item8 data_item13
data_item3 data_item9 data_item14
data_item4 data_item10
data_item5 data_item11
data_item6
I have the data in a hashMap, with the queryID (i.e. query1,query2) being the key and data_items for the
corresponding queries being the values.
The values(data_items for every query) are in a list.
Therefore, my hash map looks like this :
HashMap<String,List<String>> hm = new HashMap<String,List<String>>();
How can I write this data, column by column to a csv, as demonstrated above, using JAVA ?
I tried CSVWriter, but couldn't do it. Can anyone please help me out ?
csv files are mostly used to persist data structured like a table... meaning data with columns and rows that are in a close context.
In your example there seems to be only a very loose connection between query1, 2 and 3, and no connection horizontally between item 1,7 and 12, or 2, 8 and 13 and so on.
On top of that writing into files are usually facilitated along rows or lines. So you open your file write one line, and then another and so on.
So to write the data columnwise as you are asking, you have to either restructure your data in your code alrady to have all the data which is written into one line available on writing that line, or run through your csv file and it's lines several times, each time adding another item to a row. Of course the latter option is very time consuming and would not make much sense.
So i would suggest if there is really no connection between the data of the 3 queries, you either write your data into 3 different csv files: query1.csv, 2.csv and 3.csv.
Or, if you have a horizontal connection i.e. between item 1,7 and 12, and so on you write it into one csv file, organizing the data into rows and columns. Something like:
queryNo columnX columnY columnZ
1 item1 item2 item3
2 item7 item8 item9
3 item12 item13 item14
How to do that is well described in this thread: Java - Writing strings to a CSV file.
Other examples you can also find here https://mkyong.com/java/how-to-export-data-to-csv-file-java/
After days of tinkering around, I finally succeeded. Here is the implementation :
for(int k=0;k<maxRows;k++) {
List<String> rowValues = new ArrayList<String>();
for(int i=0;i<queryIdListArr.length;i++) {
subList = qValuesList.subList(i, i+1);
List<String> subList2 = subList.stream().flatMap(List::stream).collect(Collectors.toList());
if(subList2.size()<=k) {
rowValues.add("");
}else{
rowValues.add(subList2.get(k));
}
}
String[] rowValuesArr = new String[rowValues.size()];
rowValuesArr = rowValues.toArray(rowValuesArr);
// System.out.println(rowValues);
writer.writeNext(rowValuesArr);
}
maxRows : Size of the value list with max size. I have a list of values for each key. My hash map looks like this
HashMap<String,List<String>> hm = new HashMap<String,List<String>>();
queryIdListArr : List of all the values obtained from the hash map.
qValuesList : List of all the value lists.
List<List<String>> qValuesList = new ArrayList<List<String>>();
subList2 : sublist obtained from qValuesList using the below syntax :
qValuesList.subList(i, i+1);
rowValuesArr is an array that gets populated with the index wise value for each
value fetched from qValuesList.
The idea is to fetch all the values for each index from all the sublists and then write those values to the row. If for that index, no value is found, write a blank character.

Jedis HMSET map insertion order

Jedis has a hmset method which allows you to set a map of fields and their values at a specific key.
I use the method this way:
Map<String, String> map = new LinkedHashMap<String, String>();
// General player data
map.put("name", player.getName());
map.put("ip", player.getAddress().getAddress().getHostAddress());
map.put("rank", "none");
map.put("tokens", "0");
map.put("coins", "0");
// Arsenal player statistics
map.put("ar_score", "0");
map.put("ar_gameswon", "0");
map.put("ar_gameslost", "0");
map.put("ar_kills", "0");
map.put("ar_deaths", "0");
pipeline.hmset("uuid:" + uuid, map);
pipeline.sync();
core.redis.getJedisPool().returnResourceObject(jedis);
I decided to use a LinkedHashMap to retain the insertion order — however, when looking at the database, it still messes up the order.
Does anyone know how to insert it into the database without messing up the order?
Thank you.
The String-based Jedis client transcodes the strings using a temporary HashMap, so it kills your order. The BinaryClient iterates over the Map directly and retains the order.
The lettuce client keeps the order of your map in any case.
Alternatively, set the values one by one using HSET hash key value
HTH, Mark
Give a try to Redis based framework for Java - Redisson. It keeps map entries in insertion order during iteration using any codec (Jackson JSON, Avro, Smile, CBOR, MsgPack, Kryo, FST, LZ4, Snappy and JDK Serialization).

Google trends api results in java

I am using Google trends to get trends for particulate keyword. it will returning JSON but main problem is that i want to create class that holds data and used in java code as array List.
I am confused what is the class structure for it when i get result look like below
{"version":"0.6","status":"ok","sig":"1248242565",
"table":
{ "cols":
[{"id":"date","label":"Date","type":"date","pattern":""},
{"id":"query0","label":"linkedin","type":"number","pattern":""},
{"id":"query1","label":"facebook","type":"number","pattern":""}],
"rows":[{"c":[{"v":new Date(2004,0,1),"f":"January 2004"},{"v":0.0,"f":"0"},{"v":0.0,"f":"0"}]},
{"c":[{"v":new Date(2004,5,1),"f":"June 2004"},{"v":0.0,"f":"0"}, {"v":0.0,"f":"0"}]},
{"c":[{"v":new Date(2004,8,1),"f":"September 2004"},{"v":0.0,"f":"0"},{"v":0.0,"f":"0"}]},
{"c":[{"v":new Date(2013,9,1),"f":"October 2013"},{"v":1.0,"f":"1"},{"v":83.0,"f":"83"}]}]
}
}
It will return row and cols on search query if i search two individual word the the result is like above JSON. nay idea to how can i can make class Trend.java and that list object that holds all this informations
How would you represent those values? I'd go for a List<HashMap<String, String>> implementation.
You can assign each item in a row to a HashMap with the column header as the key. So:
HashMap<String, String> row = new HashMap<String, String>();
row.put("id", "c");
// add the rest.
Then you can cycle through each row, and request the column data by name. This will also make for some very semantically nice code!

find item from item name lookup api

I'm currently working on a project,
I need something that I can provide a name, then it can return what kind of item it is.
Say I have word starcraft,
then the API or some database can return something like game
or nba -> sports
or nike -> sports/shoe
or sadkljasd -> unknown
I saw something did this like months ago, but I can not recall.
I need something that has this kind functionality and data, and it does not have to be accurate
Anyone has any idea?
Thanks a lot
HashMap provides the kind of API you are looking for..
You can have a mapping from your item to their type.. In a Map, you store your mapping in the form of Key-Value Pair... If all your items are unique, it will be the best bet for you..
Here I will give a brief example of how a Map works.. Rest you can get from the link I have given..
Map<String, String> mapping = new HashMap<String, String>();
mapping.put("nba", "sports");
String type = mapping.get("nba");
System.out.println(type); // Will give you `sports`
And if you have multiple types for some items, you can have a Mapping from items to the list of their types: -
Map<String, ArrayList<String>> mapping =
new HashMap<String, ArrayList<String>>();
Use Collection.....
- Using Map will be appropriate at this stage...
Eg:
Map<String, ArrayList<String>> map = new HashMap<String,ArrayList<String>>();
Or
Map<String, String> map = new HashMap<String,String>();

Is is possible to store a SQLite table in Shared Prefs on Android

I need to take around 100 rows from a table and put them into the shared prefs then delete the database install a fresh and compare values.
I would only need to store 2 values from each row. Column A and column B, but I don't know if this is even possible?
Cheers for any help.
you can't store a table, but if your table really is that simple (or even if it isn't... I think you can store as much data as you feel like, really), you can transfer it over to a JSON object, stringify and store that. Then pack it back into JSON and over into your new table when you're ready to use it again.
I can also suggest to use a generic lib for abstraction of local store.
Here you have an example:
Use this android lib: https://github.com/wareninja/generic-store-for-android
import com.wareninja.opensource.genericstore.GenericStore;
// step.1: transfer data fromt able into GenericStore (aka cache)
String objKey = "mytable01";
int storeType = GenericStore.TYPE_SHAREDPREF;
//keep in mind that you can also use GenericStore.TYPE_MEMDISKCACHE
// which will store on disk cache, which can be faster and better for memory allocation
LinkedHashMap<String, Object> dataMap = new LinkedHashMap<String, Object>();
// fill in all the data from you table, e.g.
dataMap.put("row1", "val1");
GenericStore.saveObject(storeType, objKey, dataMap, mContext);
// now everything is on stored/cached
// step.2: get data back
dataMap = (LinkedHashMap<String, Object>) GenericStore.getObject(storeType, objKey, mContext);
...
Social Coding # Aspiro TV

Categories

Resources