Check if 'Key' exists in a hashmap [duplicate] - java

This question already has answers here:
HashMap<String, Integer> Search for part of an key? [duplicate]
(8 answers)
Closed 8 years ago.
I have a hashmap with Key and Value being 'String'. I want to check if a particular key exists by ignoring string after '$' in the Key.
Hashmap contains keys as 'acctId$accountId', 'acctId$desc', 'acctId$crncyCode' etc.
Iterator itx = uiToSrvFldMapList.entrySet().iterator();
if(uiToSrvFldMapList.containsKey(cellId)){
String sSrvFld = (String) uiToSrvFldMapList.get("acctId");
System.out.println("sSrvFld :: " +sSrvFld);

public static void main(String[] args) {
String s = "acctId$accountId";
s = s.replaceAll("\\$.*", "");// remove everything after $
System.out.println(s);
// do hm.get(s) here
}

I hope this might help you
Map map = new HashMap();
map.put("abc$def","ABC");
map.put("ab","A");
map.put("de","b");
String key = "abc$def";
String s[] = key.split("$");
if(map.containsKey(s[0]))
System.out.println("Value is: "+map.get(key));
else
System.out.println("cannot find..");

Supposing that in "acctId$accountId" you will have the same String both as "acctId" and "accountId", you can search for it in the following way:
`Map<String, String> uiToSrvFldMapList = new HashMap<String, String>();
uiToSrvFldMapList.put("0000$0000", "test"); // just an example
uiToSrvFldMapList.put("0000$0001", "description"); // just an example
uiToSrvFldMapList.put("0001$0000", "2test"); // just an example
uiToSrvFldMapList.put("0001$0001", "2description"); // just an example
String acctId = "0000"; // the account id string
if(uiToSrvFldMapList.containsKey(acctId +"$" + acctId)){
String sSrvFld = (String) uiToSrvFldMapList.get(acctId + "$" + acctId);
System.out.println("sSrvFld :: " +sSrvFld);
}`

This is a test program, which shows a way to achieve this functionality:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
public class Test {
public static void main(String[] args) {
Map<String, String> uiToSrvFldMapList = new HashMap<String, String>();
uiToSrvFldMapList.put("acctId$accountId", "accid");
uiToSrvFldMapList.put("acctId$desc", "accdesc");
uiToSrvFldMapList.put("acctId$crncyCode", "currencyCode");
uiToSrvFldMapList.put("smthElse$smthElse", "smthElse");
List<String> valuesContainingKey = valuesContainingKeys(
uiToSrvFldMapList, "acctId");
// Returns if the key is contained
if (valuesContainingKey.isEmpty()) {
System.out.println("The key is not contained in the map");
} else {
System.out.println("The part of the key is in the map");
}
System.out
.println("All values, where the corresponding key contains the subkey: ");
for (String s : valuesContainingKey) {
System.out.println(s);
}
}
/**
*
* #param map
* Map containing the key-value pairs
* #param searchString
* A String used as a subkey, for which is searched if it is
* contained as a substring at the beginning of a key in the map
* #return List of all Values from the map, whose corresponding key contains
* searchString
*/
private static List<String> valuesContainingKeys(Map<String, String> map,
String searchString) {
List<String> containingKeys = new ArrayList<String>();
for (Entry<String, String> e : map.entrySet()) {
if (e.getKey().startsWith(searchString)) {
containingKeys.add(e.getValue());
}
}
return containingKeys;
}
}
Simply write the method valuesContainingKeys (not needed to be static) where you want this functionality. This method will return a list of all values, whose corresponding key contains the string you are looking for. Simply checking valuesContainingKey.isEmpty() will return if there is no value, for which the corresponding key begins with the searched key.

Related

Recursive key search in JsonElement does not return value [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I am facing a problem with a relatively simple recursive function, I adapted from Find value for a key from a dynamic json using java. The function consists of searching for a key (arg1) in a nested JsonElement (arg2) and if the key is matched in the input, returning its corresponding value. The original method consisted of a void method that would have stored the value(s) in a static list but I need to change the method to return a String.
The problem I am facing is that, although the algorithm manages to search recursively within the structure of the JSON when it finds the right key and returns its value, it does not actually exit the method due to the recursive calling of the method itself. This is explained in this link: Java Return not exiting method (loops). Hence, the method always returns a "No value" string.
I have tried different tactics to solve this but unsuccessfully.
Can I please ask your help to solve this?
import java.util.Map;
import java.util.Set;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
public class Utils {
public Utils() {}
public String searchJson(String key, JsonElement jsonElement) {
String value = "No value";
// If input is an array, iterate through each element
if (jsonElement.isJsonArray()) {
for (JsonElement jsonElement1 : jsonElement.getAsJsonArray()) {
searchJson(key, jsonElement1);
}
}
else {
// If input is object, iterate through the keys
if (jsonElement.isJsonObject()) {
Set<Map.Entry<String, JsonElement>> entrySet = jsonElement
.getAsJsonObject().entrySet();
for (Map.Entry<String, JsonElement> entry : entrySet) {
// If key corresponds to the
String key1 = entry.getKey();
if (key1.equals(key)) {
value = entry.getValue().toString();
return value;
}
// Use the entry as input, recursively
searchJson(key, entry.getValue());
}
}
// If input is element, check whether it corresponds to the key
else {
if (jsonElement.toString().equals(key)) {
value = jsonElement.toString();
return value;
}
}
}
return value;
}
public static void main(String[] args) {
Utils utils = new Utils();
// Create JSON response
String response = "{\"jsonData\":[{\"cards\":[{\"card\":\"MTE14019797\",\"Explanation\":{\"Message\":\"No explaination key identified\",\"Status\":\"Failed\"},\"Prediction\":{\"Confidence_intervals\":[{\"confidence\":\"0.614\",\"distance\":\"0.3\",\"range_lower\":\"1.117\",\"range_upper\":\"1.717\"}],\"Message\":\"\",\"Status\":\"Success\",\"point_estimate\":\"1.417\"}},{\"card\":\"MTE14019798\",\"Explanation\":{\"Message\":\"No explaination key identified\",\"Status\":\"Failed\"},\"Prediction\":{\"Confidence_intervals\":[{\"confidence\":\"0.584\",\"distance\":\"0.3\",\"range_lower\":\"1.852\",\"range_upper\":\"2.452\"}],\"Message\":\"\",\"Status\":\"Success\",\"point_estimate\":\"2.152\"}}],\"Status\":\"Success\",\"modelTarget\":\"MTEter\",\"modelType\":\"conformalRegression\",\"modelUpdated\":\"2020-09-01\",\"principalResults\":[\"point_estimate\",\"confidence\",\"distance\",\"modelUpdated\"]}]}\r\n";
JsonParser parser = new JsonParser();
JsonObject json = parser.parse(response.toString()).getAsJsonObject();
System.out.println(json.toString());
System.out.println();
// Access card response
JsonArray cardResponse = json.get("jsonData").getAsJsonArray()
.get(0).getAsJsonObject()
.get("cards").getAsJsonArray();
// Iterate through individual responses
Iterator<JsonElement> cardIter = cardResponse.iterator();
while (cardIter.hasNext()) {
// Select next card
JsonObject card = cardIter.next().getAsJsonObject();
System.out.println(card);
String key = "Status";
// TODO: Replace with variable from map
// If selected card Id corresponds to that in the iterator,
// then search for the value associated to the selected end-point
String cardId = card.get("card").getAsString();
if (cardId.equals("MTE14019798")) {
String value = utils.searchJson(key, card);
System.out.print(value);
}
}
}
}```
You are not returning the value in recursive calls hence it is getting lost , you can save your return value in a variable and check for null, if it's not null you have found the value and you can break from any loops and return from recursive function.
I have modified some parts, Go through it. Also, Add null checks wherever required.
class Utils {
public Utils() {
}
public String searchJson(String key, JsonElement jsonElement) {
String value = null;
// If input is an array, iterate through each element
if (jsonElement.isJsonArray()) {
for (JsonElement jsonElement1 : jsonElement.getAsJsonArray()) {
value = searchJson(key, jsonElement1);
if (value != null) {
return value;
}
}
} else {
// If input is object, iterate through the keys
if (jsonElement.isJsonObject()) {
Set<Map.Entry<String, JsonElement>> entrySet = jsonElement
.getAsJsonObject().entrySet();
for (Map.Entry<String, JsonElement> entry : entrySet) {
// If key corresponds to the
String key1 = entry.getKey();
if (key1.equals(key)) {
value = entry.getValue().toString();
return value;
}
// Use the entry as input, recursively
value = searchJson(key, entry.getValue());
if (value != null) {
return value;
}
}
}
// If input is element, check whether it corresponds to the key
else {
if (jsonElement.toString().equals(key)) {
value = jsonElement.toString();
return value;
}
}
}
return value;
}
}
class Main {
public static void main(String[] args) {
Utils utils = new Utils();
// Create JSON response
String response = "{\"jsonData\":[{\"cards\":[{\"card\":\"MTE14019797\",\"Explanation\":{\"Message\":\"No explaination key identified\",\"Status\":\"Failed\"},\"Prediction\":{\"Confidence_intervals\":[{\"confidence\":\"0.614\",\"distance\":\"0.3\",\"range_lower\":\"1.117\",\"range_upper\":\"1.717\"}],\"Message\":\"\",\"Status\":\"Success\",\"point_estimate\":\"1.417\"}},{\"card\":\"MTE14019798\",\"Explanation\":{\"Message\":\"No explaination key identified\",\"Status\":\"Failed\"},\"Prediction\":{\"Confidence_intervals\":[{\"confidence\":\"0.584\",\"distance\":\"0.3\",\"range_lower\":\"1.852\",\"range_upper\":\"2.452\"}],\"Message\":\"\",\"Status\":\"Success\",\"point_estimate\":\"2.152\"}}],\"Status\":\"Success\",\"modelTarget\":\"MTEter\",\"modelType\":\"conformalRegression\",\"modelUpdated\":\"2020-09-01\",\"principalResults\":[\"point_estimate\",\"confidence\",\"distance\",\"modelUpdated\"]}]}\r\n";
JsonParser parser = new JsonParser();
JsonObject json = parser.parse(response.toString()).getAsJsonObject();
System.out.println(json.toString());
System.out.println();
// Access card response
JsonArray cardResponse = json.get("jsonData").getAsJsonArray()
.get(0).getAsJsonObject()
.get("cards").getAsJsonArray();
// Iterate through individual responses
Iterator<JsonElement> cardIter = cardResponse.iterator();
while (cardIter.hasNext()) {
// Select next card
JsonObject card = cardIter.next().getAsJsonObject();
System.out.println(card);
String key = "Status";
// TODO: Replace with variable from map
// If selected card Id corresponds to that in the iterator,
// then search for the value associated to the selected end-point
String cardId = card.get("card").getAsString();
if (cardId.equals("MTE14019798")) {
String value = utils.searchJson(key, card);
System.out.print(value);
}
}
}
}

Java Enums Issue

I have a below program, My enum has value "2" but it just doesn't work the way it is expected. Any help will be appreciated.
package com.deepak.streams;
import com.google.common.collect.ImmutableMap;
import java.util.HashMap;
import java.util.Map;
public class Demo2 {
public static void main(String[] args) {
if (Scores.scoreMap.containsKey("2")) {
System.out.println("Contains Value");
} else {
System.out.println("Does not contains Value");
}
}
public enum Scores {
PASS(1), FAIL(2), MATRIC(3), PROMOTED(4);
private Integer alias;
private static final Map<Object, Scores> scoreMap;
Scores(Integer iAlias) {
alias = iAlias;
}
static {
final Map<Object, Scores> tmpMap = new HashMap<Object, Scores>();
for(final Scores scores : Scores.values()) {
tmpMap.put(scores.alias, scores);
tmpMap.put(scores.name(), scores);
}
scoreMap = ImmutableMap.copyOf(tmpMap);
}
public Integer getAlias() {
return alias;
}
public static Scores getStudentScoreEnum(Integer intVal) {
return getScores(intVal);
}
public static Scores getStudentScoreEnum(String strVal) {
return getScores(strVal);
}
private static Scores getScores(Object objVal) {
if(null != objVal && !scoreMap.containsKey(objVal)) {
throw new IllegalArgumentException("Unknown Value: " + objVal);
}
return scoreMap.get(objVal);
}
}
}
Your map key is an Object:
final Map<Object, Scores> tmpMap = new HashMap<Object, Scores>();
This means it can be any Java Object. When you use put twice:
tmpMap.put(scores.alias, scores);
tmpMap.put(scores.name(), scores);
your map will now contain two new keys. The first one is an Integer since the argument, scores.alias, is an Integer. The second one is a String.
When you perform a lookup on "2", it won't find the Integer key, because "2" is a String, and "2".equals(x) is false for any x that isn't a String. Put simply, the string "2" does not equal the Integer 2.
If you really want to look up keys using String representations of integers as the key, you'll need to use a String as a key when adding to the map. That is:
tmpMap.put(scores.alias.toString(), scores);
Your best bet is to declare the map as having a String key, instead of Object, so that problems like this will be caught at compile time--unless you really want to be able to use both Integer and String values to do your lookups.
Your map contains a binding for the integer 2, not the string "2". The name mapping will be "MATRIC" -> enumValue.

WordCount Method

I don't understand why my code is not working. I get an error: "cannot find symbol - method getLength()," which is defined in the Array class. Any suggestions about how to make this method better? Thank you!
/**
* getWordCount
*
* Get a count of how many times each word occurs in an input String.
*
* #param text a string containing the text you wish to analyze
* #return a map containing entries whose keys are words, and
* whose values correspond to the number of times that word occurs
* in the input String text.
*/
public Map<String,Integer> getWordCount(String text)
{
String[] parts = text.trim().split("('s|\\W)+");
Map<String, Integer> wordCountMap = new TreeMap<String, Integer>();
for(int i=0;i<parts.getLength();i++)
{
for(String text : parts[i].toString())
{
if(!wordCountMap.containsKey(text))
{
wordCountMap.put(text,1);
} else {
int freq = wordCountMap.get(text);
freq++;
wordCountMap.put(text,freq);
}
return wordCountMap;
}
return new TreeMap<String,Integer>();
}
}
There is more than one issue with your code.
The following changes might help
public Map<String,Integer> getWordCount(String text)
{
String[] parts = text.trim().split("('s|\\W)+");
Map<String, Integer> wordCountMap = new TreeMap<String, Integer>();
for (String part : parts)
{
if(!wordCountMap.containsKey(part))
{
wordCountMap.put(part,1);
} else {
int freq = wordCountMap.get(part);
freq++;
wordCountMap.put(part,freq);
}
}
return wordCountMap;
}
The following test code gives a size of 5 which seems to confirm what you looking to do in your code.
Map<String, Integer> map = getWordCount(" the fox jumped over the moon ");
System.out.println("size:" + map.size());

How To Access The Value in HashTable

I want to access the value in hashtable but in my code there is a exception . I want to access the constructor values of another class within the (KEY,VALUE) in the hastable this is the code of my class
public class StudentReg {
public String RegNo,Program ,FName;
StudentReg(int Roll , String Program, String FName)
{
this.RegNo = " Fall2k14_ " + Roll + " " + Program;
this.FName = FName;
this.Program = Program;
}
And Now i I have used a hashtable in which i want to access the values of the hastable using iterator this is the code of my main class And I have created a object T of hashtable and entered the key and the value set and get the values in the iterator
public static void main(String[] args){
Hashtable T = new Hashtable();
T.put("Ahmed", new StudentReg(123,"BS(CS)","Murtaza"));
T.put("Fahad", new StudentReg(456,"BE(EE)","...."));
T.put("Alan", new StudentReg(769,"BBA","Rashee"));
Set set =T.keySet(); // get set-view of keys
// get iterator
Iterator itr = set.iterator();
while(itr.hasNext()) {
StudentReg S3 = (StudentReg) itr.next();
System.out.println(S3 + ": " +T.get(S3.RegNo+""+S3.Program+""+S3.FName));
}
At this point System.out.println(S3 + ": " +T.get(S3.RegNo+""+S3.Program+""+S3.FName)); i want to access the values which has been passed in the constructor of StudentReg();
but i am unable to do that
You are iterating on your keys which are Strings. If you want to iterate on all objects that are of the StudentReg class, you want to iterate on values().
I strongly recommend to add type parameters to the collections. This way your code would not compile, and you would see right away what the problem is.
Hashtable<String, StudentReg> T
= new Hashtable<String, StudentReg>();
or if using java 7 or newer
Hashtable<String, StudentReg> T = new Hashtable<>();
Then you can iterate on the values() using a foreach construct.
for (StudentReg s : T.values()) {
System.out.println(T.RegNo + " " + T.Program + " " + T.FName));
}
You are trying to cast the String... the keyset returns all the keys, not values...
If you want the keys and values you can do like this:
public static void main(String[] args) {
Hashtable<String, String> hashtable = new Hashtable<String, String>();
hashtable.put("a", "1");
hashtable.put("b", "2");
for (Entry<String, String> tuple : hashtable.entrySet()) {
System.out.println(tuple.getKey(), tuple.getValue());
}
}

Map of Map - word pairs in java - stuck

I am using a MSDOS windows prompt to pipe in a file.. its a regular file with words.(not like abc,def,ghi..etc)
I am trying to write a program that counts how many times each word pair appears in a text file. A word pair consists of two consecutive words (i.e. a word and the word that directly follows it). In the first sentence of this paragraph, the words “counts” and “how” are a word pair.
What i want the program to do is, take this input :
abc def abc ghi abc def ghi jkl abc xyz abc abc abc ---
Should produce this output:
abc:
abc, 2
def, 2
ghi, 1
xyz, 1
def:
abc, 1
ghi, 1
ghi:
abc, 1
kl, 1
jkl:
abc, 1
xyz:
abc, 1
My input is not going to be like that though. My input will be more like:
"seattle amazoncom is expected to report"
so would i even need to test for "abc"?
MY BIGGEST issue is adding it to the map... so i think
I think i need to use a map of a map? I am not sure how to do this?
Map<String, Map<String, Integer>> uniqueWords = new HashMap<String, Map<String, Integer>>();
I think the map would produce this output for me: which is axactly what i want..
Key | Value number of times
--------------------------
abc | def, ghi, jkl 3
def | jkl, mno 2
if that map is correct, in my situation how would i add to it from the file?
I have tried:
if(words.contain("abc")) // would i even need to test for abc?????
{
uniqueWords.put("abc", words, ?) // not sure what to do about this?
}
this is what i have so far.
import java.util.Scanner;
import java.util.ArrayList;
import java.util.TreeSet;
import java.util.Iterator;
import java.util.HashSet;
public class Project1
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
String word;
String grab;
int number;
// ArrayList<String> a = new ArrayList<String>();
// TreeSet<String> words = new TreeSet<String>();
Map<String, Map<String, Integer>> uniquWords = new HashMap<String, Map<String, Integer>>();
System.out.println("project 1\n");
while (sc.hasNext())
{
word = sc.next();
word = word.toLowerCase();
if (word.matches("abc")) // would i even need to test for abc?????
{
uniqueWords.put("abc", word); // syntax incorrect i still need an int!
}
if (word.equals("---"))
{
break;
}
}
System.out.println("size");
System.out.println(uniqueWords.size());
System.out.println("unique words");
System.out.println(uniqueWords.size());
System.out.println("\nbye...");
}
}
I hope someone can help me because i am banging my head and not learnign anything for weeks now.. Thank you...
I came up with this solution. I think your idea with the Map may be more elegant, but run this an lets see if we can refine:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
public class Main {
private static List<String> inputWords = new ArrayList<String>();
private static Map<String, List<String>> result = new HashMap<String, List<String>>();
public static void main(String[] args) {
collectInput();
process();
generateOutput();
}
/*
* Modify this method to collect the input
* however you require it
*/
private static void collectInput(){
// test code
inputWords.add("abc");
inputWords.add("def");
inputWords.add("abc");
inputWords.add("ghi");
inputWords.add("abc");
inputWords.add("def");
inputWords.add("abc");
}
private static void process(){
// Iterate through every word in our input list
for(int i = 0; i < inputWords.size() - 1; i++){
// Create references to this word and next word:
String thisWord = inputWords.get(i);
String nextWord = inputWords.get(i+1);
// If this word is not in the result Map yet,
// then add it and create a new empy list for it.
if(!result.containsKey(thisWord)){
result.put(thisWord, new ArrayList<String>());
}
// Add nextWord to the list of adjacent words to thisWord:
result.get(thisWord).add(nextWord);
}
}
/*
* Rework this method to output results as you need them:
*/
private static void generateOutput(){
for(Entry e : result.entrySet()){
System.out.println("Symbol: " + e.getKey());
// Count the number of unique instances in the list:
Map<String, Integer>count = new HashMap<String, Integer>();
List<String>words = (List)e.getValue();
for(String s : words){
if(!count.containsKey(s)){
count.put(s, 1);
}
else{
count.put(s, count.get(s) + 1);
}
}
// Print the occurances of following symbols:
for(Entry f : count.entrySet()){
System.out.println("\t following symbol: " + f.getKey() + " : " + f.getValue());
}
}
System.out.println();
}
}
In your table, you have Key | Value | Number of times. Is the "nubmer of times" specific to each of second words? This may work.
My suggestion in your last question was to use a map of Lists. Each unique word would have an associated List (empty to begin with). At the end of processing you would count up all identical words in the list to get a total:
Key | List of following words
abc | def def ghi mno ghi
Now, you could count identical items in your list to find out that:
abc --> def = 2
abc --> ghi = 2
abc --> mno = 1
I think this approach or yours would work well. I'll put some code together and update this post is nobody else responds.
You have initialized uniqueWords as a Map of Maps, not a Map of Strings as you are trying to populate it. For your design to work, you need to put a Map<String, Integer> as the value for the "abc" key.
....
Map<String, Map<String, Integer>> uniquWords = new HashMap<String, Map<String, Integer>>();
System.out.println("project 1\n");
while (sc.hasNext())
{
word = sc.next();
word = word.toLowerCase();
if (word.matches("abc")) // would i even need to test for abc?????
// no, just use the word
{
uniqueWords.put("abc", word); // <-- here you are putting a String value, instead of a Map<String, Integer>
}
if (word.equals("---"))
{
break;
}
}
Instead, you could do something akin to the following brute-force approach:
Map<String, Integer> followingWordsAndCnts = uniqueWords.get(word);
if (followingWordsAndCnts == null) {
followingWordsAndCnts = new HashMap<String,Integer>();
uniqueWords.put(word, followingWordsAndCnts);
}
if (sc.hasNext()) {
word = sc.next().toLowerCase();
Integer cnt = followingWordsAndCnts.get(word);
followingWordsAndCnts.put(word, cnt == null? 1 : cnt + 1);
}
You could make this a recursive method to ensure that each word gets its turn as the following word and the word that is being followed.
for each key (e.g. "abc") you want to store another string (e.g. "def","abc") paired with an integer(1,2)
I would download google collections and use a Map<String, Multiset<String>>
Map<String, Multiset<String>> myMap = new HashMap<String, Multiset<String>>();
...
void addPair(String word1, String word2) {
Multiset<String> set = myMap.get(word1);
if(set==null) {
set = HashMultiMap.create();
myMap.put(word1,set);
}
set.add(word2);
}
int getOccurs(String word1, String word2) {
if(myMap.containsKey(word1))
return myMap.get(word1).count(word2);
return 0;
}
If you don't want to use a Multiset, you can create the logical equivalents(for your purposes, not general purpose):
Multiset<String> === Map<String,Integer>
Map<String, Multiset<String>> === Map<String, Map<String,Integer>>
To make your answer in alphabetically order... Simply make all HashMap into TreeMap. For example:
new HashMap>();'
into
new TreeMap>();
and dont forget to add import java.util.TreeMap;

Categories

Resources