Specify which function was used on string within a map - java

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.

Related

A proper way to make an HashMap with multiple value type

I have an object the represent an entity. By example i have the "user" java object that have the followings field, String name, String first name, String address, boolean deadOrAlive. But now instead of having field i want to put them into a hashmap, so my first reflex was to make it this way :
private HashMap<String, Object> fieldsHM;
This would means that i have to cast my HM value when i want to use it and i don't want to make that because i need to know the type before i use my value. I want to make something like :
Set<String> keys = fieldsHM.keySet();
for(String key : keys) {
if(fieldsHM.get(key).isBoolean()) {
// Do the appropriate things
} else {
// Do the thing for this case...
}
}
I think it's possible in java, would this be good to do it this way ?
EDIT 1: I don't want to make a hashMap because this is not what i need. What i need is a way to browse the fields of the Entity user fields by fields, and depending the type of the field do the appropriate things.
I don't want to make a hashMap because this is not what i need. What i
need is a way to browse the fields of the Entity user fields by
fields, and depending the type of the field do the appropriate things.
I guess that would be a job for Reflection, like User.class.getFields().
It will still be uncomfortable to distinguish between primitive field, but you could use their wrapper classes instead.
But whatever path you choose, I think there would be a better solution if you would state what the actual goal is.
Depending on your actual use case, it might make sense to use JSON (maybe with databind) or even a database.
You could use the heterogeneous container pattern, but I would abandon the map idea and use a proper object.

how to remove nested entry in a nested map using dot notation

I have a nested map, something like this:
map.get("employee").get("address").remove("city")
Is there a way to remove the city entry using a key like "employee.address.city"? So I am looking for something like MapUtil.remove(map,"employee.address.city")
Java 8 library Dynamics can do this, it wraps a nested map/collection (amongst other types) structure and allows null-safe reasoning without static typing.
Dynamic.from(map).get("employee").get("address").asMap().remove("city");
We wrap the map to obtain our Dynamic instance, #get now returns other Dynamic instances representing the child, or absence of that child. As such this is null-safe.
For convenience we can also use #dget to split a get into many, and perhaps #maybe to handle the cases where the employee or address don't exist without exception:
Dynamic.from(map).dget("employee.address")
.maybe().asMap()
.ifPresent(address -> address.remove("city"));
See more examples https://github.com/alexheretic/dynamics
Not natively, no, though you could write yourself a method to parse your extended map key using String.split("\\."), like this:
public void nestedRemove(Map map, String keyToRemove)
{
String string = "employee.address.city";
String[] keys = string.split("\\.");
Map subMap = null;
for(int i = 0; i < keys.length -1; i++)
{
subMap = subMap.get(keys[i]);
}
subMap.remove(keys[i]);
}
You could write your own method to do this, although you'd be likely to have to resort to a fair amount of casting. You'd probably just split on dots, then keep calling get (and remembering the result for the next step) until you got to the last part, at which point you'd call remove instead... remembering to check for a null return from get at every step.
I don't know of anything built into a third party library to do this - which isn't to say it's nowhere, of course.

Java Arrays: Identify elements of a vector with constants

I have a String array (String[]) containing several String objects representing XPath queries. These queries are predetermined at design time. This array is passed to an object who executes the queries and then returns a Map<String, ArrayList<String>> with the results.
The map is made like this:
{Query that originated the result, Results vector}
Since I have to take these results and then perform some work with them, I need to know the individual queries. e.g.:
ArrayList<String> firstQueryResults = xpathResults.getObject(modelQueries[0]);
... logic pertaining only to the first query results ...
Retrieving the results by an integer (in the case of the first query, "0") doesn't seem nice to me, so I was wondering if there would be the possibility to identify them via enum-like constants, for better clarity:
... = xpathResults.getObject(QueryDictionary.MODEL_PACKAGE);
... = xpathResults.getObject(QueryDictionary.COMPONENT_PACKAGE);
OR
... = xpathResults.getObject(ModelQueries.PACKAGE);
... = xpathResults.getObject(ComponentQueries.PACKAGE);
I thought of using maps (i.e. Map<String, String> as in Map {ID, Query}) but I have still to reference the queries via an hardcoded string (e.g. "Package").
I also thought of using enums but i have several query sets (Model, Component, ...) and I also need to get all the query in a set in a String[] form in order to pass them to the object who performs the queries.
You can use a marker interface:
public interface QueryType {
}
Then your enums can implement this interface:
public enum ModelQueries implements QueryType {
...
}
public enum ComponentQueries implements QueryType {
...
}
and so on.
Then your getObject method can accept a parameter of type QueryType. Were you looking for something like this? Let me know if I haven't understood your question properly.

Mapping data structure in 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"

Convert strings to Java objects automatically

I want to convert user input that comes as Map<String, String[]> to objects in Java. More specically I want to convert the params of a HttpServletRequest to the fields of an arbitrary domain object.
I'd like to have something like this:
Domain d = Converter.convert(params, new Domain());
If there is more than one element in the string array, which is the value of a map entry, it should be converted to a list or array. Maybe the locale should be considered for date and currency conversion. And a list of conversion errors would be nice.
Is there a library with such a converter?
Would you call it "converter"? I think it is often called "data binding", but that is the wrong term in my opionion, since it is related to binding model values to GUI elements, what is a slightly different thing - isn't it?
If your web framework does not support this functionality have a look at
http://commons.apache.org/beanutils/ ,espeically the beanutils package which has classes with similar purposes (maybe exactly the same) that you want.
You may also consider switching to a more mature framework ;-)
Don't use this plain code as it is only an example. You should add some pretty exception handling and a loop through a map. But generally the idea is like this:
void putValue(String name, String value, Object object) throws Exception {
String setterName = "set"+name.substring(0,1).toUpperCase()+name.substring(1);
Method m = object.getClass().getMethod(setterName, String.class);
if (m!=null) {
m.invoke(object, value);
}
}
This code, given a parameter name 'name' will try to find a method setName(String name) and call it with the given value.

Categories

Resources