I need to validate the value of a parameters passed as part of REST API. These parameters are a fixed set of values. I thought of using a map having parameter name as key and enum as value. So I can check if the value sent in REST API is one of the enum keys.
But I am not able to create a Map with String key and enum value in java, tried creating Map and then putting and enum as value, but it fails.
class Validation {
enum Type {
INTERNAL,
EXTERNAL
};
}
Map<String, Object> validationMap = new HashMap<String, Object>();
validationMap.put("type", Validation.Type);
This is throwing an error that type is not defined.
This is probably what you're looking for, Map<String, Object> is changed to Map<String, Validation.type>:
Map<String, Validation.type> validationMap = new HashMap<String, Validation.type>();
validationMap.put("type", Validation.type.INTERNAL);
validationMap.put("type2", Validation.type.EXTERNAL);
Your original code would have worked, if you had changed Validation.type to Validation.type.INTERNAL for example, however your validationMap map allows the storage of any Object, so validationMap.put("type2", 123.123); would also have worked, which is unlikely to be something you want.
Is this what you need?
Map<String, List<Validation.type>> validationMap = new HashMap<>();
validationMap.put("type",
Arrays.asList(Validation.type.EXTERNAL,Validation.type.INTERNAL));
I believe Your code does not work because Validation.Type is not an instance (of an enum). When you put a value in your map, I believe you would want to put in an actual instance as a value. I suppose that is why the above answers suggest adding an actual instance to the Map such as Type.INTERNAL or using a class instance.
This code will run
Map<String, Object> validationMap = new HashMap<String, Object>();
// this works
validationMap.put("type", Validation.Type.EXTERNAL);
// as shown by:
System.out.println(validationMap.toString());
// here is an analogy:
// make an instance of a class
Validation validation = new Validation();
// this works
validationMap.put("classType",validation);
Validation validationGet = (Validation) validationMap.get("classType");
System.out.println(validationMap.toString());
// by analogy this will not work because Validation is not an instance:
// validationMap.put("classType",Validation);
And the output on my machine is:
{type=EXTERNAL}
{type=EXTERNAL, classType=Validation#3feba861}
Related
Usually, if I know beforehand all the keys of a map, I instantiate it like this:
List<String> someKeyList = getSomeList();
Map<String, Object> someMap = new HashMap<String, Object>(someKeyList.size());
for (String key : someKeyList) {
someMap.put(key, null);
}
Is there any way to do this directly without needing to iterate through the list? Something to the effect of:
new HashMap<String, Object>(someKeyList)
My first thought was to edit the map's keyset directly, but the operation is not supported. Is there other way I'm overlooking?
You can use Java 8 Streams :
Map<String,Object> someMap =
someKeyList.stream()
.collect(Collectors.toMap(k->k,k->null));
Note that if you want a specific Map implementation, you'll have to use a different toMap method, in which you can specify it.
I have a multi-line value that needs to be processed. I'm using the map.get() method to retrieve that value but it seems to be getting only the last line value.
Here's my code:
map = new LinkedHashMap();
updateMap("BUG", parser, map, bugRec);
map.put(nextBuildIdTagName, nextBuildId); // putting the new value in
String value = (String)map.get(nextBuildIdTagName); // This is where it is not working
nextBuildIdTagName already has a value, and the new value gets inserted as a new line. I need to be able to retrieve the existing value as well as the new value.
So from what I understand you want to store multiple values in the map under single key. Easiest way to do it (without using any external lib with multimap impl) is to create a map of lists like this:
Map<String, List<String>> map = new HashMap<>();
then when you add to map you can do sth like this:
if(!map.containsKey(nextBuildIdTagName)) {
map.put(nextBuildIdTagName, new ArrayList<>());
}
map.get(nextBuildIdTagName).add(nextBuildId);
then to get all the items and iterate over them
for(String value : map.get(nextBuildIdTagName)) {
// do sth to each line
}
In the javadoc for HashMap (of which LinkedHashMap is a subclass), it is clearly stated that: "If the map previously contained a mapping for the key, the old value is replaced". To store multiple values (the lines) for the same key, you'd need to do something like:
Map<String, List<String>> map = new Linked HashMap<>();
And the add to the list (which is the map value) the needes lines. Note: here I assumed your key to be a String, change its type as needed.
Source: http://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html#put(K,%20V)
How can I pass in a new HashMap in the most canonical (simplest, shortest hand) form?
// 1. ? (of course this doesn't work)
passMyHashMap(new HashMap<String, String>().put("key", "val"));
// 2. ? (of course this doesn't work)
passMyHashMap(new HashMap<String, String>(){"key", "val"});
void passMyHashMap(HashMap<?, ?> hm) {
// do stuff witih my hashMap
}
Create it, initialize it, then pass it:
Map<String,String> myMap = new HashMap<String,String>();
myMap.put("key", "val");
passMyHashMap(myMap);
You could use the "double curly" style that David Wallace mentions in a comment, I suppose:
passMyHashMap(new HashMap<String,String>(){{
put("x", "y");
put("a", "b");
}});
This essentially derives a new class from HashMap and sets up values in the initializer block. I don't particularly care for it (hence originally not mentioning it), but it doesn't really cause any problems per se, it's more of a style preference (it does spit out an extra .class file, although in most cases that's not a big deal). You could compress it all to one line if you'd like, but readability will suffer.
You can't call put and pass the HashMap into the method at the same time, because the put method doesn't return the HashMap. It returns the old value from the old mapping, if it existed.
You must create the map, populate it separately, then pass it in. It's more readable that way anyway.
HashMap<String, String> map = new HashMap<>();
map.put("key", "val");
passMyHashMap(map);
HashMap< K,V>.put
public **V** put(K key,V value)
Associates the specified value with the specified key in this map. If
the map previously contained a mapping for the key, the old value is
replaced.
Returns the previous value associated with key, or null if there was
no mapping for key. (A null return can also indicate that the map
previously associated null with key.)
As you can see, it does not return the type HashMap<?, ?>
You can't do that. What you can do is create a factory that allow you to do so.
public class MapFactory{
public static Map<String, String> put(final Map<String, String> map, final String key, final String valeu){
map.put(key, value);
return map;
}
}
passMyHashMap(MapFactory.put(new HashMap<String, String>(),"key", "value"));
Although I can't image a approach that would need such implementation, also I kinda don't like it. I would recommend you to create your map, pass the values and just then send to your method.
Map<String, String> map = new HashMap<String, String>();
map.put("key","value");
passMyHashMap(map);
I need to create a Hashmap of field/values contained in an Entity, so I can can use them to replace them in a String containing tags with the field names.
I have this code:
public static String replaceTags(String message, Map<String, String> tags) ...
Which replaces all tags found in message for the equivalent values in tags, but in order to build the Map table I need to take "any" Entity and be able to create a Map from the Entity. So, how could I make that possible? to get a routine where I send the Entity and get as return a Map with all the fields and values.
public static Map<String, String> getMapFromEntity(Object entity){
Map<String, String> map = new HashMap<String, String>();
...?????
return map;
}
I know I could use reflection and this is the only approach I have found to get this done, but is there any other way to accomplish the same?, I mean a more efficient way.
Thanks.
Field[] fields = entity.getClass().getFields();
Map<String, String> map = new HashMap<String, String>();
for(Field f : fields)
map.put(f.getName(),(String) f.get(entity));
O, and your entity should be an object of your class, not your class itself.
If your fields are private and you have getters for them, you should use getMethods() and check if method name starts with "get" prefix.Like this:
Method[] methods = entity.getClass().getMethods();
Map<String, String> map = new HashMap<String, String>();
for(Method m : methods)
{
if(m.getName().startsWith("get"))
{
String value = (String) m.invoke(entity);
map.put(m.getName().substring(3), value);
}
}
If all you want to get out of this is a map, why not use a literary like Jackson, then you can simply convert it like this
Map map = new ObjectMapper().convertValue(object, Map.class);
I know I could use reflection and this is the only approach I have
found to get this done, but is there any other way to accomplish the
same?
As far as I know, reflection is the only way to accomplish this, unless the class(es) you want to build the map from implement some interface, and your code extracting the map is aware of this interface.
For my Android app I've the need of defining some keys in a single constant, and I think the best way to do it is using a map. But not sure whether that's really the way to go, and how to do it correctly. As I'm targeting Android, a Bundle may also be an option.
I have a list of keys like:
"h" = "http"
"f" = "ftp"
Basically the program is to read a QR code (to keep that code from growing too big I'm using super-short keys), gets those keys, and has to translate them to something useful, in my case a protocol.
I'm trying to define a constant called KEY_PROTOCOLS, I think this should be a Map, so later I can call something like KEY_PROTOCOLS.get("f") to get the protocol that belongs to key "f".
Other classes should also be able to import this constant, and use it. So this map has to be populated in the class right away.
How can I do this?
If the constant is shared by several classes, and if you want to make sure this map is not cleared or modified by some code, you'd better make it unmodifiable :
public static final Map<String, String> KEY_PROTOCOLS;
static {
Map<String, String> map = new HashMap<String, String>();
map.put("f", "ftp");
// ...
KEY_PROTOCOLS = Collections.unmodifiableMap(map);
}
Something like this:
private static final Map<String, String> KEY_PROTOCOLS = new HashMap<String, String>();
static{
KEY_PROTOCOLS.put("f", "ftp");
// More
}
Static Initialisers:
http://www.glenmccl.com/tip_003.htm
This would work.
static Map<String, String> map = new HashMap<String, String>();
static {
map.add("ftp", "ftp");
...
}
On android:
#SuppressWarnings("unchecked")
Pair<String,String>[] pre_ips=new Pair[]{new Pair<String,String>("173.194", "0"), new Pair<String,String>("74.125", "96")};
String ip_1_2,ip_3;
for (Pair<String,String> pre_ip:pre_ips)
{ip_1_2=pre_ip.first;
ip_3=pre_ip.second;
}