I'm doing a personal project.
After a lot of maps, I came to the point where I want to enter a map inside another map... Let me explain better.
I have this Map atPropostas which have information about a person, but at some time of the program, I want to add to that person a boss email.
private Map<String, Long> atPropostas;
private Map<String,Map<String,Long>> atOrientadores;
To add that boss email, I've done this:
for (Map.Entry<String, Long> atprop : atPropostas.entrySet()) {
for (Map.Entry<String, Proposta> prop : propostas.entrySet()) {
if (prop.getValue().getTipo().equals("T2") && propostas.containsKey(atprop.getKey())) {
atOrientadores.put(prop.getValue().getEmailDocente(), atprop);
}
}
}
But, atprop value, inside atOrientadores.put() it produces an error:
java: incompatible types:
java.util.Map.Entry<java.lang.String,java.lang.Long> cannot be
converted to java.util.Map<java.lang.String,java.lang.Long>
I have tried to cast the atprop:
atOrientadores.put(prop.getValue().getEmailDocente(), (Map<String, Long>) atprop);
And the compiler error disappears, but the App itself, doesn't working.
You can't convert Map.Entry in to a Map with casting.
Map and entry represent inherently different notions. Map consists of entries, it isn't an entry.
You can create a single entry map by using static method Map.ofEntries() available with Java 9
atOrientadores.put(prop.getValue().getEmailDocente(), Map.ofEntries(atprop));
Sidenote: it's highly advisable to use English while giving names to variables, classes, etc. in your application. It makes it easier to reason about your code.
I don't know for sure what atprop is meant to represent, but you've mentioned a person and an email. I advise you to consider creating classes that would correspond to a person and an email instead of complicating your code and dealing with nested maps.
Related
We are using the java EE 7 with Wildfly 10.0. In the last few days I am learning a lot of Bean validation feature that is included in Java EE 7 specification. It sounds promising, as I see many advantages in using annotations for validations including reusabilty and cleaner code.
However the javax.validation.Validator returns a Set of ConstraintViolations.
Now, the ConstraintViolation has a message attached to it which you can get from it with getMesssage(). The type of the message is a String.
However, for our error handling we use a custom type that we created called a Pair<int, String>, to return message to the client including error code and a message.
Here is an example of how our pairs look like:
public static final Pair<Integer, String> NAME_VALIDATION_ERROR = new Pair<Integer, String>(
201, "Name must contain only letters");
Now, this is all in a class called ErrorStrings and it's easy to use because that class contains static methods and when you start typing ErrorStrings. the autocomplete gives you the names of the error pairs you can use. For example NAME_VALIDATION_ERROR.
So, what would be the easiest way to add Pair<int, String> to the ConstraintViolation, so that it can be used to return the response to the client without adding complexity to the code.
I thougth of adding a Hashmap<String, Pair<int, String>> to the ErrorStrings class, and using a message defined in ConstraintViolation as a key, but that would add much complexity to that class as you would have to change a pair and a hashmap when you would like to change or add some error.
I am using a hibernate validator, which is a default implementation for Jave EE, but I am willing to use any other implementation. I would like to know the easiest way, to redefine ConstraintViolation so it has Pair<int, String> in it.
The "easiest" way I know is that you should create your own custom contraints, which would throw custom ConstraintViolation implementations, which could also have a public Pair<Integer, String> getMessagePair() method. But this would be even more complex, as it would require you to reimplement every single validation you do.
Personally I would do the translation from String to Pair<Integer, String> in a new ErrorStringTranslator class. This is a bit cleaner solution than the one you mentioned, but doesn't save you from the complexity of the task.
I have a method in an android application:
public void changeImageView (HashMap<String,String> Detail)
I have been trying to call this method in the onCreate method in the same class.
I have tried:
changeImageView();
and
changeImageView(HashMap<String,String> Detail);
Both of which give me errors. The first gives me an error stating that the parameters are missing - understandable. But when I try the second version, I get an error saying "expression expected" with HashMap<String,String>.
I am probably missing something very obvious and have been unable to find anything online that can answer my question.
First, create an instance of HashMap<String, String>.
Map<String, String> map = new HashMap<>();
After its filling or other operations on the map, pass it as a parameter to your method.
changeImageView(map);
I would suggest you reading about methods on Oracle Tutorials.
HashMap is a collection class available in java.util package.
A method changeImageView() here has a definition which takes a HashMap object of type [Generic Type : Google it to know more about it].
You need to create a HashMap object :
Map<String,String> map=new HashMap<String,String>();
You can add values to the above hashmap as given below :
map.add("key1","value1");
map.add("key2","value3");
depending upon your requirements.
Now you can pass this map object to the changeImageView() method as given below:
changeImageView(map)
Seems like you are a newbie to Java and OOP , please refer any Java basic tutorials . This will help you to build up your basic concepts.
Currently am using Hazelcast and persistence database as Hbase,
So far I have 10 maps, for each map am using a map store, So Am using 10 mapstore classes (i.e) In all the 10 classes am implementing the MapStore. It creates a complexity in maintenance.
So What I did is, I kept a generic map store and implemented the same class for all the maps, It has the ability to accept it, To make it clear, I did something like
Map1 - com.test.GenericMapStore
Map2 - com.test.GenericMapStore
Map3 - com.test.GenericMapStore
...
Map10 - com.test.GenericMapStore
It gets mapped as above,
But for the methods in store, storeAll, loadAllKeys, loadAll am able to check the instance of object and find the mapName ---- Not a good way
But for methods like delete, deleteAll, load - I dont have any clue to find the mapName,
Pls tell me like any way to use a singleMapStore for all the maps???
So I need a map store implementation where, for all methods in mapstore, I need the PARAM called mapName to be passed, So In case, If I have common Implementation, I can make use of it just by using MAP NAME param in all the methods,
Example :
Store(String key, Object object, String mapName),
StoreAll(Map, String mapName),
delete(String key, String mapName)
delete(Collections keys, String mapName) ...
If there is a way already available, Pls do let me know...
Thanks hazelcast team,,, You ppl are doing the great job... Much Apprecaiated...
Thanks and Regards,
Harry
You should be able to achieve this with a MapStoreFactory (docs).
The MapStoreFactory is called with the name of the map and you can pass that name into the GenericMapStore.
In you MapStoreFactory :
public MapLoader newMapStore(mapName, props) {
return new GenericMapStore(mapName);
}
then in GenericMapStore you will have the mapName for each operation.
Say I have made Objectify4 work with my project (although I am still working on making it work) is it possible to persist an Entity with Map field like this:
class Foo {
Map<String, Object> map;
public Foo() {}
public Foo(Map map) {
this.map = map;
}
}
The basic idea is to be able to store/persist a "generic" field that can be either
java.lang.String
java.lang.Number
java.lang.Boolean
null
java.util.List
java.util.Map
For example I can store this:
map.put("uid:sarah:fname", "Sarah");
persist(new Foo(map));
Or
map.put("uid:sarah:age", 25);
persist(new Foo(map));
Is this even possible with Objectify? or App Engine?
This will work as-is with Objectify4, with a couple caveats:
You can't use the '.' character in the key name
The Object value will not be translated at all; it will be whatever the datastore accepts.
1 is because this ends up being stored in the raw Entity as field.keyname (with possibly several layers of '.' separating embedded fields).
2 is because you're removing any type information so Objectify just treats Object as-is. It's like you're using the low-level api directly; you can only store primitives or collections of primitives. No arrays, certainly no Maps. Collections always come back as List. Numbers always come back as Long no matter what size they are stored as. There are some other quirky behaviors too.
If you really want this behavior, you can create a custom TranslatorFactory which will introspect the types at runtime and do just about anything you want. This is pretty advanced, however, and will require some study of the existing translators. We can help you out on the Google Group; stackoverflow is probably not the right place for this discussion.
Is there a library that can do the following?:
Given an Object and a HashMap, it enumerates the keys of the Hashmap and looks up the setters for these keys in the Object and sets the associated values. Something looking like that:
public Object setData(Object object, HashMap<String, Object> fields) {
for (Entry<String, Object> entry : fields.entrySet()) {
Method m = object.getClass().getMethod("set" + entry.getKey(), entry.getValue().getClass());
if (m != null) {
m.invoke(object, entry.getValue());
}
}
return object;
}
The task looks simple at the first look but there are some nuances that I hope someone has already taken care of. As you know, reinventing the wheel (the good wheel) is a bad approach.
Look at Apache Commons BeanUtils
org.apache.commons.beanutils.BeanUtils.populate(Object bean, Map properties)
Javadoc:
Populate the JavaBeans properties of the specified bean, based on the specified name/value pairs. This method uses Java reflection APIs to identify corresponding "property setter" method names, and deals with setter arguments of type String, boolean, int, long, float, and double.
Better use BeanUtils class:
public Object setData(Object object, HashMap<String, Object> fields) {
for(Entry<String, Object> entry : fields.entrySet()) {
BeanUtils.setProperty(object, entry.getKey(), entry.getValue());
}
return object;
}
I have a BeanAsMap class that I wrote a long time ago. The method asMap returns a Map that is a view on a Java bean (POJO). You can call putAll on that Map, passing it the Map that you want to copy data from.
Feel free to use my code mentioned above.
Example:
MyClass bean = ...;
Map<String, Object> inputData = ...;
Map<String, Object> view = BeanAsMap.asMap(bean);
view.putAll(inputData);
BeanUtils is fine.
But, as good practice, i would not write code that use reflection. Or as the last solution i have, if none other has been found.
This code cannot be tracked in IDE like Eclipse (no call hierarchy), making the developer think that the setters are never called. He can break your code and that will still compile.
Too high level of abstraction like this makes the code difficult to understand.
Code that is being obfuscated will be broken by the obfuscator itself when writting such things.
Best solution would be to rethink the use of reflection to set the object fields.
Check out http://commons.apache.org/beanutils/, in particular BeanUtils.populate():
http://commons.apache.org/beanutils/v1.8.3/apidocs/index.html