Mapping data structure in Java - java

I have to devise a function that will take as input a keyword and will output a category id.
Ex:
f('dog') returns _ANIMAL
f('chair') returns _FURNITURE
I already have the mapping and I could just iterate over the tag array each time, but I have a feeling this is not the best solution.
Is there a special data structure (I'm thinking of ternary search trees) in the Java libraries for this specific task? Should I just use HashMap (or maybe Set (since there are few categories))?
P.S. This mapping is fixed, I do not need to add or remove elements from it once it is built.

If I understand you correctly, then HashMap sounds like exactly what you want. You wouldn't want to iterate through an entire array each time, because with many function calls and/or a large array your program would wind up running slowly. With a HashMap, pulling a value (your category) from a key (your keyword) happens more or less immediately, in constant time.
You can build the map like this:
HashMap map = new HashMap();
map.put("dog", "animal");
map.put("chair", "furniture");
map.put("cat", "animal");
And then map.get("dog") returns "animal", map.get("chair") returns "furniture".
As others have indicated, enums would work well (and a tiny bit faster) for this too—with the caveat that they're fixed at compile time and thus cannot be changed during execution.

You can change your enum like the following:
public enum Things{
_ANIMAL("Dog"), _FURNITURE("Animal");
private String description;
Things(String description){
this.description= description;
}
public String toString(){
return description;
}
};
Whenever you want to retrieve the string representation of your enum, just call toString
Example:
Things._ANIMAL.toString() will output "Dog"

Related

Specify which function was used on string within a map

I have a map of strings that all need to be modified by one of several functions based on some conditions.
My problem is that once I return the map, I need someway to identify which function was used on that specific string. My current idea is to add an identfier at the end of each string so I can check.
Ex. In the case the function "HPV" was used : mystring = mystring + "HPV"
Then on the return end, I can check the end of the string and know which function was used.
Is this an appropriate solution or is there a more efficient way that does not involve checking and modifying every single string?
You should probably use an object that can return both the actual String and the identifier of the function that did the work on it.
If the functions that will do the work are all known at compile-time, they can be identified by an enum, otherwise just another String that holds their ID.
Here is a simple suggestion on how to do that:
enum StringModifier {
HPV, OTHER
}
record ModifiedString(
String string,
StringModifier modifier
) {}
main(String[] args) {
Map<String, String> originalMap = ...
Map<String, ModifiedString> modifications = transform(originalMap, ...)
}
This avoids allocating new Strings and "dirty-ing" them, which can give you trouble later to clean them up as you probably want to make sure you know what the actual result String should look like.

Unique representation of String for in-memory cache in Java

I am trying to build in-memory cache (using a ConcurrentHashMap in Java 8).The key value pair would be a json string and the result of a complex operation on that string.
The objective is to not do the complex operation everytime and do it only when the json string changes.
Is there a way I can uniquely represent this string as the value of any of the json keys can change within the application at any time.
I have looked up the hashCode() method but saw the shortcomings of it.
Right now am trying to see if the MD5 representation of the string would serve as a good key for the JSON string.
If anyone has already faced such a situation, can you please provide your inputs?
As I understand it, a java String instance is final (immutable), so that even if the JSON object is a very long string, the String class only calculates the hashCode of the String once (at construction time or first use i can't remember) - and keeps it as an instance attribute for the lifetime of the String. So there is no problem (in terms of performance penalty) using the JSON object both as the key and value in a concurrent HashMap. This is exactly what the same as how a java "Set" works, being backed by a Map.
This should be a easy task for Cacheonix, and you will save time on building your own caching solution:
Cache<String, ResultOfCalculation> cache = Cacheonix.getInstance().getCache("my.cache");
cache.put(myJsonString, myResultofCalcualtion);
...
ResultOfCalculation result = cache.get(myJsonString);

4 Key Value HashMap? Array? Best Approach?

I've got loads of the following to implement.
validateParameter(field_name, field_type, field_validationMessage, visibleBoolean);
Instead of having 50-60 of these in a row, is there some form of nested hashmap/4d array I can use to build it up and loop through them?
Whats the best approach for doing something like that?
Thanks!
EDIT: Was 4 items.
What you could do is create a new Class that holds three values. (The type, the boolean, and name, or the fourth value (you didn't list it)). Then, when creating the HashMap, all you have to do is call the method to get your three values. It may seem like more work, but all you would have to do is create a simple loop to go through all of the values you need. Since I don't know exactly what it is that you're trying to do, all I can do is provide an example of what I'm trying to do. Hope it applies to your problem.
Anyways, creating the Class to hold the three(or four) values you need.
For example,
Class Fields{
String field_name;
Integer field_type;
Boolean validationMessageVisible;
Fields(String name, Integer type, Boolean mv) {
// this.field_name = name;
this.field_type = type;
this.validationMessageVisible = mv;
}
Then put them in a HashMap somewhat like this:
HashMap map = new HashMap<String, Triple>();
map.put(LOCAL STRING FOR NAME OF FIELD, new Field(new Integer(YOUR INTEGER),new Boolean(YOUR BOOLEAN)));
NOTE: This is only going to work as long as these three or four values can all be stored together. For example if you need all of the values to be stored separately for whatever reason it may be, then this won't work. Only if they can be grouped together without it affecting the function of the program, that this will work.
This was a quick brainstorm. Not sure if it will work, but think along these lines and I believe it should work out for you.
You may have to make a few edits, but this should get you in the right direction
P.S. Sorry for it being so wordy, just tried to get as many details out as possible.
The other answer is close but you don't need a key in this case.
Just define a class to contain your three fields. Create a List or array of that class. Loop over the list or array calling the method for each combination.
The approach I'd use is to create a POJO (or some POJOs) to store the values as attributes and validate attribute by attribute.
Since many times you're going to have the same validation per attribute type (e.g. dates and numbers can be validated by range, strings can be validated to ensure they´re not null or empty, etc), you could just iterate on these attributes using reflection (or even better, using annotations).
If you need to validate on the POJO level, you can still reuse these attribute-level validators via composition, while you add more specific validations are you´re going up in the abstraction level (going up means basic attributes -> pojos -> pojos that contain other pojos -> etc).
Passing several basic types as parameters of the same method is not good because the parameters themselves don't tell much and you can easily exchange two parameters of the same type by accident in the method call.

Newbie: Using a variable as the rhs argument to the dot operator? [duplicate]

This question already has answers here:
Dynamic variable names Java
(3 answers)
Closed 9 years ago.
I have a list of objects and I'll need to access a specific one based off of random user input corresponding to an id. My limited knowledge at this point led me to something like:
String id;
if(id.equals("apple")){ //fixed silly error, thanks
return objectList.id.memberName;
} //etc...
Is this possible, or is there a better approach?
Sounds like you want a HashMap.
It works like a telephone directory - you put in keys and values, and use the key to look up a value (much like you'd use someone's name to look up their number in a telephone directory.)
Your example also wouldn't work at all, because you're using = in the if statement, which is an assignment statement rather than an equality check. == is what you were probably trying to get, but in this case you shouldn't use that either - instead use .equals() which you should always use when strings are concerned.)
HashMap<String, SomeValueObject> myMap = new HashMap<String, SomeValueObject>();
myMap.put("apple", value);
String id;
if (id.equals("apple")) {
return myMap.get("apple");
}
Essentially you instantiate a HashMap that has two parts to it; a Key and a Value (respectively. When I do myMap.get("apple"), it searches for the KEY "apple". I did myMap.put("apple", value) which makes the Key "apple" be mapped to a certain value that you want.
Also you need to use id.equals("apple") because a String is an object, and if you tried id == "apple" (which I think you meant), it will not work because it will not compare the value of the String but rather the address of it.
#berry120 has provided a practical answer. In general, it sounds like you want to lookup values based on some key. Look at the Map interface and what the JDK offers for concrete implementations.
The value of a variable is only available at run time. On the other hand, a variable name must be known at compile time. So no, you cannot do this exactly the way you are asking. Using a Map will probably be the best solution to your problem.

How to get the key when a corresponding value is used instead?

I am using Android 2.1 SDK, the application reads from the Sqlite database, a table that has two columns, an id, and a string.
I read in this into a HashMap<Long, String>, the value part of it gets displayed in a List, now, I wish to obtain the key value, so I cooked up this simple routine:
private Map.Entry<Long, String> getEntry(String sValue){
for (Iterator<Map.Entry<Long, String>> itMap = this.dbMap.entrySet().iterator(); itMap.hasNext();) {
Map.Entry<Long, String> curr = itMap.next();
if (curr.getValue().equalsIgnoreCase(sValue)) return curr;
}
return null;
}
My problem is being conscious of cpu cycles being chewed up in respect to Android, battery/cpu time, in looking for the value in the HashMap, that could be seen as a potential cycles of cpu lost.
Is there an easier and more efficient way of doing this instead of iterating?
The reasoning is that I can home in on the id, and directly delete the record from the table or even update it.
Um... it looks like the String should be the key, and the id the value. Which assumes that the Strings are unique, but so does your code.
Alternatively, can't your list keep the ID that corresponds to an entry around invisibly? This is how you'd usually do it (e.g. in Swing or in a HTML select).
Realistically, the only way to avoid having to iterate through is to keep two HashMaps (i.e. pay the memory cost) where one HashMap is the reverse of the first. You can create the reverse-lookup HashMap when you create your forward-lookup HashMap without having to loop through your data twice. That should give you low constant time access in both directions.
If you use an Adapter you can access the ID using the getItemID() method.

Categories

Resources