Recover the value of a hashmap that is in another hashmap - java

I want to retrieve the value of key in a Hashmap that is in another Hashmap,
static HashMap<String , HashMap<String, Float>> terms = new HashMap();
static String date;
public static void main(String[] args) throws FileNotFoundException, ParseException, IOException {
InputStream ips=new FileInputStream(filePath);
InputStreamReader ipsr=new InputStreamReader(ips);
BufferedReader br=new BufferedReader(ipsr);
String ligne;
while ((ligne=br.readLine())!=null){
JSONParser jsonParser = new JSONParser();
JSONObject jsonObject = (JSONObject) jsonParser.parse(ligne);
date = (String) jsonObject.get("created_at");
String text = (String) jsonObject.get("text");
Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_36);
List<String> ss=TokenizewithAnalyzer.tokenizeString(analyzer, text);
for(String s : ss){
ajoutFrequence(s, date);}
System.out.print("==>"+ss+" \n");}
for(Entry <String, HashMap<String, Float>> entry : terms.entrySet()){
// float res=entry.getValue().get(date).floatValue();
System.out.println(entry.getValue().get(date).floatValue());
}
br.close();
}
static void ajoutFrequence(String token, String date){
if(terms.containsKey(token)){
HashMap<String, Float> freqdate = terms.get(token);
if(freqdate.containsKey(date)){
freqdate.put( date, freqdate.get(date)+1);
}else{
freqdate.put(date, Float.valueOf(1));
}
}else{
HashMap<String, Float> freqdate = new HashMap<>();
freqdate.put(date, Float.valueOf(1));
terms.put(token, freqdate);
} }}
in the output I get the frequence in a list for example:
null
null
1.0
null
null
null
I want to do something like this: float freq=entry.getValue().values(); but it is impossible.Thank you in advance.

You use the date as a key in your second map. So I assume you could do following:
for(Entry <String, HashMap<String, Float>> entry : terms.entrySet()){
System.out.println(entry.getValue().get(date));
}
To access a specific value in your second map, you need to provide a key for this value. In your case, this key is a date.

I solved the problem in fact I used two loop to traverse the hashmap and I recovered the value of the second hashmap like this:
for(Entry <String, HashMap<String, Float>> entry : terms.entrySet()){
HashMap<String, Float> d=entry.getValue();
for(Entry<String,Float>ent:d.entrySet()){
float dd=ent.getValue();
System.out.println(dd);}}
At the end I got the float. Thank you.

Related

Problem adding list from on Hashmap to another

Issue adding a list from one hashmap's value to another's
Basically, I have 2 hashmaps (map1 and map2), both have the same keys(Integers from 0-500), but different values. What I'm wanting to do is use the value of map1, which is a String, as the key and the value of map2, which is a List, as the value. Adding map1 as the key is working, no problem, but when I try to add map2's value as map's value, it just returns as null.
This is for a homework project, where we are given 2 .csv files, one with labels and another with fake image file names, and have to be able to search by either image label or image file name.
Map<String, List<String>> map = new HashMap<String, List<String>>();
#SuppressWarnings({ "resource", "null", "unlikely-arg-type" })
public ImageLabelReader(String labelMappingFile, String imageMappingFile) throws IOException {
Map<Integer, String> map1 = new HashMap<Integer, String>();
Map<Integer, List<String>> map2 = new HashMap<Integer, List<String>>();
BufferedReader labelIn = new BufferedReader(new FileReader(labelMappingFile));
BufferedReader imageIn = new BufferedReader(new FileReader(imageMappingFile));
String row;
String[] rowArray;
while ((row = labelIn.readLine()) != null) {
rowArray = row.split(" ", 2);
map1.put(Integer.parseInt(rowArray[0]), rowArray[1]);
}
labelIn.close();
while ((row = imageIn.readLine()) != null) {
rowArray = row.split(" ", 2);
if(map2.containsKey(Integer.parseInt(rowArray[1]))) {
List<String> tempList = map2.get(Integer.parseInt(rowArray[1]));
tempList.add(rowArray[0]);
} else {
List<String> l = new ArrayList<String>();
l.add(rowArray[0]);
map2.put(Integer.parseInt(rowArray[1]), l);
}
}
imageIn.close();
List<String> t = new ArrayList<String>();
for(int i = 0; i < map1.size(); i++) {
t.clear();
for(String s : map2.get(i)) {
t.add(s);
System.out.println(t);
}
map.put(map1.get(i), map2.get(i));
}
System.out.println(map.containsKey("burrito"));
System.out.print(map2.get("burrito"));
}
Output is "True null" when the output should be "True [list containing strings]"
Try replacing -
map.put(map1.get(i), map2.get(i));
with
map.put(map1.get(i), t);
And also -
System.out.print(map2.get("burrito"));
with
System.out.print(map.get("burrito"));
Also, you're trying to get map's value using a String while you said the key is of int type, please check that.

encode json object params in httpurlconnection

I want post some parameters to server with httpurlconnection in android,my data is an nested JsonObject , and i must encode it first but it's wrong because i receive status error from server, this is my encode function and Jsonobject:
private static String encodeParams(JSONObject params) throws Exception {
StringBuilder result = new StringBuilder();
boolean first = true;
Iterator<String> itr = params.keys();
while(itr.hasNext()){
String key= itr.next();
Object value = params.get(key);
if (first)
first = false;
else
result.append("&");
result.append(URLEncoder.encode(key, "UTF-8"));
result.append("=");
result.append(URLEncoder.encode(value.toString(), "UTF-8"));
}
return result.toString();
}
my nested json:
JSONObject postDataParams = new JSONObject();
postDataParams.put("name", "Manjeet");
postDataParams.put("email", "manjeet#gmail.com");
JSONObject par = new JSONObject();
par.put("class", "a");
par.put("family", "aray");
postDataParams.put("par", par);
Construct a URI from the output, only encoding the characters ?#/
which is a lot easier than your loop
You can use URI's, which produce a different output and result
The following sample
new URI("http", "host.com", "/path/", "key=| ?/#ä", "fragment").toURL();
produces the result http://host.com/path/?key=%7C%20?/%23ä#fragment. Note how characters such as ?&/ are not encoded to allow for the URI Query string
(Copied from the API)
I'am not sure about this code, since i've never worked with JSONObject, but i'll try to show you the idea :
Create a method which returns all the properties of an object (including the nested one) :
Map<String, String> jobjectToMap(JSONObject jo) {
Map<String, String> properties = new HashMap<String, String>;
Iterator<String> itr = jo.keys();
while(itr.hasNext()){
String key= itr.next();
Object value = jo.optJSONObject(key);//this will returns null if the value is not a JSONObject from https://docs.oracle.com/middleware/maf242/mobile/api-ref/oracle/adfmf/json/JSONObject.html#getJSONObject-java.lang.String-
if(value != null) { //nested object
properties.putAll(jobjectToMap(value));
} else {
properties.put(key, jo.get(key)); //primitive one
}
}
return properties;
}
Create another method which transforms the map to an url
public String queryParams(Map<String, String> params)
throws UnsupportedEncodingException
{
StringBuilder queryString = new StringBuilder();
if (params.size() > 0) {
queryString.append('&');
}
// Convert the params map into a query string.
for (Map.Entry<String, String> entry : params.entrySet())
{
String encodedKey = URLEncoder.encode(entry.getKey(), "UTF-8");
String encodedValue = URLEncoder.encode(entry.getValue(), "UTF-8");
queryString.append(encodedKey);
queryString.append('=');
queryString.append(encodedValue);
}
return queryString.toString();
}

Java - Write hashmap to a csv file

I have a hashmap with a String key and String value. It contains a large number of keys and their respective values.
For example:
key | value
abc | aabbcc
def | ddeeff
I would like to write this hashmap to a csv file such that my csv file contains rows as below:
abc,aabbcc
def,ddeeff
I tried the following example here using the supercsv library: http://javafascination.blogspot.com/2009/07/csv-write-using-java.html. However, in this example, you have to create a hashmap for each row that you want to add to your csv file. I have a large number of key value pairs which means that several hashmaps, with each containing data for one row need to be created. I would like to know if there is a more optimized approach that can be used for this use case.
Using the Jackson API, Map or List of Map could be written in CSV file. See complete example here
/**
* #param listOfMap
* #param writer
* #throws IOException
*/
public static void csvWriter(List<HashMap<String, String>> listOfMap, Writer writer) throws IOException {
CsvSchema schema = null;
CsvSchema.Builder schemaBuilder = CsvSchema.builder();
if (listOfMap != null && !listOfMap.isEmpty()) {
for (String col : listOfMap.get(0).keySet()) {
schemaBuilder.addColumn(col);
}
schema = schemaBuilder.build().withLineSeparator(System.lineSeparator()).withHeader();
}
CsvMapper mapper = new CsvMapper();
mapper.writer(schema).writeValues(writer).writeAll(listOfMap);
writer.flush();
}
Something like this should do the trick:
String eol = System.getProperty("line.separator");
try (Writer writer = new FileWriter("somefile.csv")) {
for (Map.Entry<String, String> entry : myHashMap.entrySet()) {
writer.append(entry.getKey())
.append(',')
.append(entry.getValue())
.append(eol);
}
} catch (IOException ex) {
ex.printStackTrace(System.err);
}
As your question is asking how to do this using Super CSV, I thought I'd chime in (as a maintainer of the project).
I initially thought you could just iterate over the map's entry set using CsvBeanWriter and a name mapping array of "key", "value", but this doesn't work because HashMap's internal implementation doesn't allow reflection to get the key/value.
So your only option is to use CsvListWriter as follows. At least this way you don't have to worry about escaping CSV (every other example here just joins with commas...aaarrggh!):
#Test
public void writeHashMapToCsv() throws Exception {
Map<String, String> map = new HashMap<>();
map.put("abc", "aabbcc");
map.put("def", "ddeeff");
StringWriter output = new StringWriter();
try (ICsvListWriter listWriter = new CsvListWriter(output,
CsvPreference.STANDARD_PREFERENCE)){
for (Map.Entry<String, String> entry : map.entrySet()){
listWriter.write(entry.getKey(), entry.getValue());
}
}
System.out.println(output);
}
Output:
abc,aabbcc
def,ddeeff
Map<String, String> csvMap = new TreeMap<>();
csvMap.put("Hotel Name", hotelDetails.getHotelName());
csvMap.put("Hotel Classification", hotelDetails.getClassOfHotel());
csvMap.put("Number of Rooms", hotelDetails.getNumberOfRooms());
csvMap.put("Hotel Address", hotelDetails.getAddress());
// specified by filepath
File file = new File(fileLocation + hotelDetails.getHotelName() + ".csv");
// create FileWriter object with file as parameter
FileWriter outputfile = new FileWriter(file);
String[] header = csvMap.keySet().toArray(new String[csvMap.size()]);
String[] dataSet = csvMap.values().toArray(new String[csvMap.size()]);
// create CSVWriter object filewriter object as parameter
CSVWriter writer = new CSVWriter(outputfile);
// adding data to csv
writer.writeNext(header);
writer.writeNext(dataSet);
// closing writer connection
writer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
If you have a single hashmap it is just a few lines of code. Something like this:
Map<String,String> myMap = new HashMap<>();
myMap.put("foo", "bar");
myMap.put("baz", "foobar");
StringBuilder builder = new StringBuilder();
for (Map.Entry<String, String> kvp : myMap.entrySet()) {
builder.append(kvp.getKey());
builder.append(",");
builder.append(kvp.getValue());
builder.append("\r\n");
}
String content = builder.toString().trim();
System.out.println(content);
//use your prefered method to write content to a file - for example Apache FileUtils.writeStringToFile(...) instead of syso.
result would be
foo,bar
baz,foobar
My Java is a little limited but couldn't you just loop over the HashMap and add each entry to a string?
// m = your HashMap
StringBuilder builder = new StringBuilder();
for(Entry<String, String> e : m.entrySet())
{
String key = e.getKey();
String value = e.getValue();
builder.append(key);
builder.append(',');
builder.append(value);
builder.append(System.getProperty("line.separator"));
}
string result = builder.toString();

How to read two files from one folder?

The code given below takes two different inputs but I want to pass only single input that is the path of folder "test" and rest of the functioning as it is.
And also the final.tbl which is generation it should generate in the same input folder path:
public class Migrator {
private static final String KEY1 = "post_tran_id";
private static final String KEY2 = "post_tran_cust_id";
void migrate(String post_tran, String post_tran_cust) throws IOException {
Map<String, Map<String, String>> h1 = loadFile(post_tran, KEY1);
Map<String, Map<String, String>> h2 = loadFile(post_tran_cust, KEY2);
PrintStream out = new PrintStream("final.tbl");
for (Map.Entry<String, Map<String, String>> entry : h1.entrySet()) {
Map<String, String> data = entry.getValue();
String k = data.get(KEY2);
if (k != null && h2.containsKey(k)) {
print(out, KEY1, data.get(KEY1));
print(out, KEY2, data.get(KEY2));
// Print remaining rows in any order
for (String key : data.keySet()) {
if ( ! key.equals(KEY1) && ! key.equals(KEY2) ) {
print(out, key, data.get(key));
}
}
data = h2.get(k);
for (String key : data.keySet()) {
if ( ! key.equals(KEY2) ) {
print(out, key, data.get(key));
}
}
out.println(); // Record separator
}
}
}
private void print(PrintStream out, String key, String data) {
out.print("[name]");
out.print(key);
out.print("[/name]");
out.print("=");
out.print("[data]");
out.print(data);
out.print("[/data]");
out.println();
}
private Map<String, Map<String, String>> loadFile(String fileName, String key) throws
IOException {
Map<String, Map<String, String>> result = new HashMap<String, Map<String, String>>
();
BufferedReader br = new BufferedReader(new FileReader(fileName));
String line;
do {
Map<String, String> data = new HashMap<String, String>();
while ((line = br.readLine()) != null && !line.isEmpty()) {
data.put(getKey(line), getData(line));
}
result.put(data.get(key), data);
} while (line != null);
br.close();
return result;
}
private String getKey(String line) {
String[] tokens = line.split("=");
int length = tokens[0].length();
return tokens[0].substring(6, length - 7);
}
private String getData(String line) {
String[] tokens = line.split("=");
int length = tokens[1].length();
return tokens[1].substring(6, length - 7);
}
public static void main(String[] args) throws IOException { Migrator mg =
new Migrator();
mg.migrate("D:\\test\\post_tran.tbl",
"D:\\test\\post_tran_cust.tbl"); }
}
To make your migrate method take 1 argument but be able to work with many paths, you can always append all the paths into one string and parse them inside the migrate method.
Example:
String appendedArgument = "D:\\test\\post_tran.tbl;D:\\test\\post_tran_cust.tbl";
Notice the semi-colon separating both paths.
Then you can call you method:
mg.migrate(appendedArgument);
And parse it on the other side:
void migrate(String argument) throws IOException
{
String[] splitArgument.split(";");
String post_tran = splitArgument[0];
String post_tran_cust = splitArgument[1];
Map<String, Map<String, String>> h1 = loadFile(post_tran, KEY1);
Map<String, Map<String, String>> h2 = loadFile(post_tran_cust, KEY2);
}
Using this kind of method you can send as many paths into your migrate method as you want, this enables you (in this particular case) to also send the path where you want to store the final.tbl file.
That would make the appendedArgument string to look like:
String appendedArgument = "D:\\test\\;D:\\test\\post_tran.tbl;D:\\test\\post_tran_cust.tbl";
And then you would need to parse it accordingly inside the migrate method.

Save and Load nested Map into text file using Java

I have a nested MAP. I want to save these Map in a text file and then use this file in another projects. I can save outerMap correctly, however I need an efficient code to load this file into same Maps (I use '#' to separating key of outerMap and its innerMap).
Map <String, Map <String,Double>> outerMap= new HashMap<>();
Map <String,Double> innerMap= new HashMap<>();
.
.
.
PrintWriter writer = new PrintWriter("e:\\t.txt", "UTF-8");
Iterator it = outerMap.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pairs = (Map.Entry)it.next();
writer.println(pairs.getKey() + "#" + pairs.getValue());
}
writer.close();
On your question in comment:
Gson gson = new Gson();
Map<String, Map<String, Double>> outerMap = new HashMap<>();
Map<String, Double> innerMap = new HashMap<>();
innerMap.put("1", 1.0);
innerMap.put("2", 2.0);
outerMap.put("key1", innerMap);
String json = gson.toJson(outerMap);
Path path = FileSystems.getDefault().getPath("", "myfile.txt");
Files.write(path, json.getBytes("UTF-8"), StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING);
json = new String(Files.readAllBytes(path));
outerMap = gson.fromJson(json, new TypeToken<Map<String, Map<String, Double>>>(){}.getType());
for (Map.Entry<String, Map<String, Double>> outerEntry: outerMap.entrySet()) {
System.out.println(outerEntry.getKey());
innerMap = outerEntry.getValue();
for (Map.Entry<String, Double> innerEntry: innerMap.entrySet()) {
System.out.println(" " + innerEntry.getKey() + "->" + innerEntry.getValue());
}
}
Output:
key1
2->2.0
1->1.0
You need use Gson library.
If you don't need human readable content in text-file, you can use approach, suggested in the first comment:
Map<String, Map<String, Double>> outerMap = new HashMap<>();
Map<String, Double> innerMap = new HashMap<>();
innerMap.put("1", 1.0);
innerMap.put("2", 2.0);
outerMap.put("key1", innerMap);
// write to file
try (ObjectOutput objectOutputStream = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("myfile2.txt", false)))) {
objectOutputStream.writeObject(outerMap);
} catch (Throwable cause) {
cause.printStackTrace();
}
// read from file
try (ObjectInput objectInputStream = new ObjectInputStream(new BufferedInputStream(new FileInputStream("myfile2.txt")))) {
outerMap = (Map<String, Map<String, Double>>) objectInputStream.readObject();
} catch (Throwable cause) {
cause.printStackTrace();
}
You will have your Map on 'outerMap' reference.
This sounds pretty straightforward to me.
(Assuming you want to load the values of the file into innerMap)
FileInputStream inputStream = new FileInputStream("e:\\t.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String buffer;
while((buffer = reader.readLine()) != null){
String[] pairs = buffer.split("#");
innerMap.put(pairs[0],Double.parseDouble(pairs[1]));
}
Pepper it with safety checks where you deem necessary.
NOTE : Sample code is written blindly and might be subject to careless mistakes.

Categories

Resources