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.
Related
I have no idea why in every Value in my Map is putted the same last record.
The Key is ok, but in every iteration my list is putted into everyone record in map.
I dont understand why..
Could someone help ?
HashMap<Long, LinesEntity> xlsMapped = new HashMap<>();
MapEntity mapEntity = new MapEntity();
LinesEntity linesEntity = new LinesEntity();
ArrayList<String> list = new ArrayList<>();
//read first line
String line = br.readLine();
String array[];
long mapKey = 0;
while (line != null) {
array = line.split(",");
list.clear();
for (String cell : array) {
list.add(cell);
}
line = br.readLine();
linesEntity.setSingleLine(list);
dataService.saveOne(linesEntity);
xlsMapped.put(mapKey, linesEntity);
mapKey++;
}
// mapEntity.setMapa(xlsMapped);
// dataService.save(mapEntity);
}
I think you need to create new linesEntity and list object instances for each loop:
while (line != null) {
linesEntity = new LinesEntity(); // create a new LinesEntity for this loop execution
list = new ArrayList()
array = line.split(",");
Which means that technically you don't need to create them at the top, just declare them:
LinesEntity linesEntity;
ArrayList<String> list;
I want to print a array list, in that array list it contains hash map and I print in a text file. while trying to print the text file it print in single line. I need in a separate line
Example:
ArrayList<Object> mainlist= new ArrayList<>();
LinkedHashMap<String, String> hmap = new LinkedHashMap<>();
for (int i=0;i<5;i++)
{
hmap.put("key1", "03-08-2018");
hmap.put("key2", "xyz";
hmap.put("key3", "123");
//ArrayList USed:::
mainlist.add(hmap);
mainlist.add("\n");
}
return mainlist;
I return in text file. It generates a single line but I need separate lines in my output text file.
Expected output in text file:
[{key1=03-08-2018,key2=xyz,key3=123}
{key1=03-08-2018,key2=xyz,key3=123}
{key1=03-08-2018,key2=xyz,key3=123}
]
Actual output in text file:
[{key1=03-08-2018,key2=xyz,key3=123},{key1=03-08-2018,key2=xyz,key3=123},{key1=03-08-2018,key2=xyz,key3=123}]
Can any one help me to out of this?
Thanks for ur reply
I tested your code and it's working for me. How Are you writing it to file?
I did it like this:
Path path = Paths.get("/test/outputXXXX.txt");
ArrayList<Object> mainlist= new ArrayList<>();
LinkedHashMap<String, String> hmap = new LinkedHashMap<>();
for (int i=0;i<5;i++)
{
hmap.put("key1", "03-08-2018");
hmap.put("key2", "xyz");
hmap.put("key3", "123");
//ArrayList USed:::
mainlist.add(hmap);
mainlist.add("\n");
}
try (BufferedWriter writer = Files.newBufferedWriter(path))
{
writer.write(mainlist.toString());
}
And output in file:
[{key1=03-08-2018, key2=xyz, key3=123},
, {key1=03-08-2018, key2=xyz, key3=123},
, {key1=03-08-2018, key2=xyz, key3=123},
, {key1=03-08-2018, key2=xyz, key3=123},
, {key1=03-08-2018, key2=xyz, key3=123},
]
EDIT:
Sorry, didin't see you need it without comma.
You can do this like that then:
Path path = Paths.get("/test/outputXXXX.txt");
ArrayList<Object> mainlist= new ArrayList<>();
LinkedHashMap<String, String> hmap = new LinkedHashMap<>();
for (int i=0;i<5;i++)
{
hmap.put("key1", "03-08-2018");
hmap.put("key2", "xyz");
hmap.put("key3", "123");
//ArrayList USed:::
mainlist.add(hmap);
mainlist.add("\n");
}
try (BufferedWriter writer = Files.newBufferedWriter(path))
{
writer.write("[");
for (Object o : mainlist) {
writer.write(o.toString());
}
writer.write("]");
}
ArrayList<Object> mainlist= new ArrayList<>();
LinkedHashMap<String, String> hmap = new LinkedHashMap<>();
for (int i=0;i<5;i++)
{
hmap.put("key1", "03-08-2018");
hmap.put("key2", "xyz"); //you missed closing paranthesis here
hmap.put("key3", "123");
//ArrayList USed:::
mainlist.add(hmap);
mainlist.add("\n");
}
return mainlist;
You can try the below code in :: https://www.tutorialspoint.com/compile_java_online.php
import java.util.*;
public class ArrayListExample{
public static void main(String args[]){
ArrayList<Object> mainlist= new ArrayList<>();
LinkedHashMap<String, String> hmap = new LinkedHashMap<>();
int i=0;
for (i=0;i<5;i++) {
hmap.put("key1", "03-08-2018");
hmap.put("key2", "xyz");
hmap.put("key3", "123");
//ArrayList USed:::
mainlist.add(hmap);
mainlist.add("\n");
}
System.out.println(mainlist);
return;
}
}
This gives your expected output. Hope this helps you.
Thanks.
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.
I am reading a HashMap and creating a CSV file.
The below code accepts a HashMap and produce a CSV file. However the formatting is a problem. For a HashMap,
HashMap<String, Integer> hmap = new HashMap<String, Integer>();
hmap.put("Feature1", 1);
hmap.put("Feature2", 2);
It produces
Feature2,Feature2,
2,1,Feature1,Feature1,
2,1,
Expected Output (without comma at the end of each line):
Feature2,Feature1
2,1
Which is a wrong formatting
This is the code I use. How to fix it ?
public String appendCSV(Map featureset) throws IOException{
StringBuilder csvReport = new StringBuilder();
Map<String, Integer> map =featureset;
Set<String> keys = map.keySet();
String[] lsitofkeys = {};
for(String elements:keys){
for(int i =0 ; i< keys.size(); i++){
csvReport.append(elements+",");
}
csvReport.append("\n");
for(String key: keys){
csvReport.append(map.get(key).toString()+",");
}
}
return csvReport.toString();
}
Java 8 has String.join():
Having collected the keys and values into lists:
csvReport.append(String.join(",", keys));
csvReport.append(String.join(",", values));
The Streams API has Collectors.joining() which helps even more:
List<Entry> entries = new ArrayList<>(map.entrySet());
csvReport.append(entries.stream()
.map(e -> e.getKey())
.collect(Collectors.joining(","));
csvReport.append("\n");
csvReport.append(entries.stream()
.map(e -> e.getValue())
.collect(Collectors.joining(","));
csvReport.append("\n");
Both of these ultimately use StringJoiner. If you have an academic interest in how to build a joined string without a delimiter at the end, it's worth looking at the code for StringJoiner for an elegant example.
However - There are subtleties to writing CSV and it's a good idea to use a library unless there are reasons (legal, academic) not to. Apache Commons CSV is one.
seems you have issues with your loop
you need two separate loops (no inner loops);
Also to get rid of that comma at the end, you can use a simple check using a isFirst variable like below :)
public String appendCSV(Map featureset) throws IOException{
StringBuilder csvReport = new StringBuilder();
Map<String, Integer> map =featureset;
Set<String> keys = map.keySet();
String[] lsitofkeys = {};
boolean isFirst=true;
for(String elements : keys){
if(!isFirst){
csvReport.append(",");
}
csvReport.append(elements);
isFirst=false;
}
csvReport.append("\n");
isFirst=true;
for(String elements : keys){
if(!isFirst){
csvReport.append(",");
}
csvReport.append(map.get(elements));
isFirst=false;
}
return csvReport.toString();
}
Just remote the last character of your string if it is longer than 1 character. Here is how to do it: str.substring(0, str.length() - 1);
You should have a separate StringBuilder for the keys and another one for the values. Then as you go through your keys you add them to your key StringBuilder and then take the map given and grab the value associated with that key and add it to your value StringBuilder.
Lastly you just keep track of how many keys you have seen so far. If the number of keys seen is not equal to the size of the map then you append a comma. But if you are on the last element according to the numOfKeys counter, then you append nothing to the end of the StringBuilders.
StringBuilder csvKeyReport = new StringBuilder();
StringBuilder csvValueReport = new StringBuilder();
Map<String, Integer> map = hmap;
Set<String> keys = map.keySet();
int numOfKeys = 0;
for(String key : keys)
{
numOfKeys++;
String comma = numOfKeys == map.size() ? "" : ",";
csvKeyReport.append(key + comma);
csvValueReport.append(map.get(key) + comma);
}
csvKeyReport.append("\n");
csvKeyReport.append(csvValueReport.toString() + "\n");
System.out.print(csvKeyReport.toString());
Output
Feature2,Feature1
2,1
One way to achieve that is doing something like this:
import java.io.IOException;
import java.util.HashMap;
public class HashMapToCSV {
public static void main(String[] args) {
HashMap<String, Integer> hmap = new HashMap<String, Integer>();
hmap.put("Feature1", 1);
hmap.put("Feature2", 2);
try {
System.out.println(appendCSV(hmap));
} catch (IOException e){
e.printStackTrace();
}
}
public static String appendCSV(HashMap<String,Integer> featureset) throws IOException{
StringBuilder csvReport = new StringBuilder();
// loop through the keySet and append the keys
for(String key: featureset.keySet()){
csvReport.append(key+",");
}
// to remove the comma at the end
csvReport.replace(csvReport.length()-1, csvReport.length(), "");
csvReport.append("\n"); // append new line
// then loop through the keySet and append the values
for(String key: featureset.keySet()){
csvReport.append(featureset.get(key)+",");
}
csvReport.replace(csvReport.length()-1, csvReport.length(), "");
return csvReport.toString();
}
}
Output
Feature2,Feature1
2,1
You should to create a new stringbuilder into the cycle:
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class NewClass {
public NewClass() throws IOException {
HashMap<String, Integer> hmap = new HashMap<String, Integer>();
hmap.put("Feature1", 1);
hmap.put("Feature2", 2);
System.out.print(appendCSV(hmap));
}
public String appendCSV(Map featureset) throws IOException {
StringBuilder csvReport = new StringBuilder();
StringBuilder csvReportVal = new StringBuilder();
Set<String> keys = featureset.keySet();
for (String elements : keys) {
csvReport.append(elements + ",");
csvReportVal.append(featureset.get(elements).toString() + ",");
}
// Excluding the latest ","
csvReport.setLength(csvReport.length() - 1);
csvReportVal.setLength(csvReportVal.length() - 1);
csvReport.append("\n" + csvReportVal.toString());
return csvReport.toString();
}
public static void main(String[] args) throws IOException {
new NewClass();
}
}
OUTPUT:
Feature2,Feature1
2,1
I have a text file containing domains like
ABC.COM
ABC.COM
DEF.COM
DEF.COM
XYZ.COM
i want to read the domains from the text file and check how many instances of domains are there.
Reading from a text file is easy but i am confused at how to check number of instances of domains.
Please help.
Split by space (String instances have method split), iterate through result array and use Map<String(domainName), Integer(count)> - when domain is in map, than increase count in map by 1, when not - put domain name in map and set 1 as a value.
Better solution is to use a Map to map the words Map with frequency.
Map<String,Integer> frequency = new LinkedHashMap<String,Integer>();
Read file
BufferedReader in = new BufferedReader(new FileReader("infilename"));
String str;
while ((str = in.readLine()) != null) {
buildMap(str);
}
in.close();
Build map method : You can split the urls in your file by reading them line by line and splitting with delimiter(in your case space).
String [] words = line.split(" ");
for (String word:words){
Integer f = frequency.get(word);
if(f==null) f=0;
frequency.put(word,f+1);
}
Find out for a particular domain with:
frequency.get(domainName)
Ref: Counting frequency of a string
List<String> domains=new ArrayList<String>(); // values from your file
domains.add("abc.com");
domains.add("abc.com");
domains.add("xyz.com");
//added for example
Map<String,Integer> domainCount=new HashMap<String, Integer>();
for(String domain:domains){
if(domainCount.containsKey(domain)){
domainCount.put(domain, domainCount.get(domain)+1);
}else
domainCount.put(domain, new Integer(1));
}
Set<Entry<String, Integer>> entrySet = domainCount.entrySet();
for (Entry<String, Integer> entry : entrySet) {
System.out.println(entry.getKey()+" : "+entry.getValue());
}
If the domains are unknown you can do something like:
// Field Declaration
private Map<String, Integer> mappedDomain = new LinkedHashMap<String, Integer>();
private static final List<String> domainList = new ArrayList<String>();
// Add all that you want to track
domainList.add("com");
domainList.add("net");
domainList.add("org");
...
// Inside the loop where you do a readLine
String[] words = line.split(" ");
for (String word : words) {
String[] wordSplit = word.split(".");
if (wordSplit.length == 2) {
for (String domainCheck : domainList) {
if (domainCheck.equals(wordSplit[1])) {
if (mappedDomain.containsKey(word)) {
mappedDomain.put(word, mappedDomain.get(word)+1);
} else {
mappedDomain.put(word, 1);
}
}
}
}
}
Note: This will work for something like xxx.xxx; if you need to take care of complex formats you need to modify the logic from wordSplit!