I'm trying to populate LinkedHashMap with for loop in order to use it in my jsf page but "put" method of hashmap overwrites the values that is held in hashmap when the new "put" method is fired.
The method is like that;
public static List<String> valuesOfEnum() throws JsonProcessingException {
Map<String, Object> newArray = new LinkedHashMap<String, Object>();
List<String> jsonObj = new ArrayList<String>();
String json = null;
for(LimanTipi limanTipi : values()){
newArray.put("id", limanTipi.getId());
newArray.put("value", limanTipi.getValue());
json = new ObjectMapper().writeValueAsString(newArray);
jsonObj.add(json);
}
return jsonObj;
}
Here's the jsf code;
<f:selectItems value="#{denizlimaniViewController.limanTipleri}" var="limanTipleri" itemValue="#{limanTipleri.id}" itemLabel="#{limanTipleri.value}"/>
With this method, I convert the hashmap into list as I couldn't populate the hashmap properly but this is not what I want because I can't use this list in <f:selectItems>.
I need to use itemValue and itemLabel representing "id" and "value" properties in hashmap.
Is there a way to handle this?
Thanks
Key get's overwritten because you always have keys as id and value. Modify your code like below:
for(LimanTipi limanTipi : values()){
newArray.put(limanTipi.getId(), limanTipi.getValue());
json = new ObjectMapper().writeValueAsString(newArray);
jsonObj.add(json);
}
EDIT:
Hope limanTipleri is the map newArray itself. Then you need to modify your code like below:
<f:selectItems value="#{denizlimaniViewController.limanTipleri.entrySet()}"
var="limanTipleri"
itemValue="#{limanTipleri.key}" itemLabel="#{limanTipleri.value}" />
Related
I would like to create multiple hashmaps from a resultset.
The final result should be something like below;
{
slot_name = recommend,
data = 7,
},
{
slot_name = service,
data = Good,
},
{
slot_name = staff,
data = Great,
},
I tried as below:
HashMap<String, String> data = new HashMap<String, String>();
while (resultSet.next()) {
data.put("slot_name", resultSet.getString("name"));
data.put("data", resultSet.getString("param_value"));
}
But when I printout the value of the hashmap, I get one record as below
System.out.println(data);
{
slot_name = staff,
data = Great,
}
How can I achieve this? Someone assist, thank you
I would recommend to have a list and create a model class(instead of HashMaps) for "slot_name" and "data". Inside loop, construct object and add to the list. The reason, you are not getting as expected, is because, HashMap will have unique keys. So, for the same key when the value is again added, it will get updated.
class YourModel {
String slotName;
String data;
}
// inside loop
list.add(new YourModel(resultSet.getString("name"), resultSet.getString("param_value"));
A HashMap is a key value store. If you put the same key more than once, previous will be overwritten. This is the reason you saw only the last entry in the output.
if you want multiple maps, well create multiple ones.
Eg.,
List<HashMap<String,String> maps = new ArrayList();
while (resultSet.next()) {
HashMap<String, String> data = new HashMap<String, String>();
data.put("slot_name", resultSet.getString("name"));
data.put("data", resultSet.getString("param_value"));
maps.add(data);
}
I am working on android application and using number picker for displaying data.
I have this json as a string:
{"Acura": ["CL", "ILX", "Integra", "Legend", "MDX", "NSX", "RDX", "RL", "RLX", "RSX", "SLX", "TL", "TLX", "TSX", "Vigor", "ZDX", "Other Acura Models"],
"Alfa": ["164", "4C", "8C Competizione", "Giulia", "GTV-6", "Milano", "Spider", "Stelvio", "Other Alfa Romeo Models"],
"AMC": ["Alliance", "Concord", "Eagle", "Encore", "Spirit", "Other AMC Models"],
"Aston": ["DB11", "DB7", "DB9", "DBS", "Lagonda", "Rapide", "Rapide S", "V12 Vantage", "V8 Vantage", "Vanquish"]} .
What I was trying get the object like, Acura, Alfa, AMC, Aston, in single arraylist. I was stuck how to get Acura models in another numberpicker ,
there I need to pass string array of data .
So this was my ambiguous situation.
Now what I need is, I have objects string array so that whenever I pick Acura, the other picker should show Acura models.
If I select Alfa, other picker shows Alfa models. For this I think I need to have hashmap. Still I am unaware how to implement that, if someone can help me out this situation. Thanks.
you need to store your data in a Map<String,List<String>> like this
Type mapType = new TypeToken<Map<String, List<String>>>() {}.getType();
Map<String, List<String>> source = new Gson().fromJson('your_json_string_here', mapType);
and then iterate over it like this :
for (Map.Entry<String, List<String>> entry : source.entrySet()) {
String key = entry.getKey();
List<String> values = entry.getValue();
//Here you can write your code to do whatever you want
}
Say I have a Map<String,String> and a POJO like below
class Model {
String name;
String value;
}
I need to populate the name and value of Model by key and value of EntrySet of Map. Apart from iterating over the Map and doing the same is there any API available that can convert this map to List or Array of populated Model.
You can always iterate over EntrySet but as far as an API is concerned, there is an Apache BeanUtils available here, which you can use to convert Map to a Class.
Use it like below :-
Map<String,String> yourMap = new HashMap<String,String>();
yourMap.put("name", "Joan");
yourMap.put("value", "30");
Model model = new Model();
try {
BeanUtils.populate(model, yourMap);
}
catch (Throwable e) {
//do something...
}
I need to create a JSONObject from a HashMap of a custom class's toString and a float value. I tried the code below hoping that it would just work:
public class MyClass {
...
public String toString() {
return "a nice string"
}
}
HashMap<MyClass,Float> map = new HashMap<MyClass,Float>();
map.put(...);
JSONObject json = new JSONObject(map);
But I get:
java.lang.ClassCastException: MyClass cannot be cast to java.lang.String
What's the best way to create this JSONObject? Thanks.
You need to change this:
HashMap<MyClass,Float> map = new HashMap<MyClass,Float>();
with
HashMap<String,Float> map = new HashMap<String,Float>();
as you said "HashMap of a custom class's toString and a float value"
You haven't mentioned how are you putting the values into the hashmap.
But if you using toString method of your custom class, then you should put it like :
MyClass m = new MyClass();
map.put(m.toString,123.45f);
Seems like you're using the org.json library. If you take a look at the code of the JSONObject class, apparently they're not using generics.
public JSONObject(Map map) {
this.map = new HashMap();
if (map != null) {
Iterator i = map.entrySet().iterator();
while (i.hasNext()) {
Map.Entry e = (Map.Entry)i.next();
Object value = e.getValue();
if (value != null) {
this.map.put(e.getKey(), wrap(value));
}
}
}
}
This map seems to handle entries with a String key and an Object value by the look of the keyPool map they use to manage unique String keys. In the comments, its also stated that:
This is used by JSONObject.put(string, object).
So it would be correct to assume the keys of the JSON objects are Strings.
Your MyClass type can't be upcasted to String directly (String is not a superclass of MyClass), that's why the constructor is actually complaining about the map, because it needs a map of the form HashMap<String,Object> (Note that there's no problem with Float and Object).
To fix the issue, you have to define a HashMap<String,Float> where you should store a String representation of your MyClass object either by using toString.
If you can't use a String you can consider using an intermediate structure that maps a code represented with a String to a certain MyClass object, so you can retain your MyClass class.
Both Gamb's and Abu's answers are correct and helped me to get to my final result.
I solved my problem like this:
HashMap<MyClass,Float> obj = functionThatReturnsThisStructure();
JSONObject jsonObj = new JSONObject();
for (Entry<MyClass,Float> entry: obj.entrySet()) {
jsonObj.put(entry.getKey().toString(), entry.getValue());
}
I'm having trouble dealing with what I thought would be a simple problem. Basically, I need a java.util.Map<String, String>, where ids end up being the map keys, and someField of my document ends up in the values.
I'm really really stuck on this, which greatly surprises me. I've tried writing a separate view:
#View(map="function(d) { if (d.someField) { emit(d.someField, null); } }", name = "someField")
and then use the following Java:
public Map<String, String> getSomeFields() throws JsonParseException, JsonMappingException, IOException {
ViewQuery q = new ViewQuery().designDocId("_design/" + entity.getSimpleName()).viewName("someField");
String result = StreamUtils.inputStreamAsString(db.queryForStream(q), false);
TypeReference<Map<String, String>> mapTypeRef = new TypeReference<Map<String,String>>() {};
// mapper is a Jackson ObjectMapper
return mapper.readValue(result, mapTypeRef);
}
This is already really ugly, but it also doesn't actually work, as it seems the JSON results that queryForStream returns includes random other stuff, rather than just the result of the query. This causes the readValue call to throw an IOException.
I've also tried using reduce to generate a single object containing all these values, but the result of that is that Couch complains the reduce doesn't reduce enough...
I would do something like this:
ViewQuery query = ...
Map<String, String> map = new HashMap<String, String>();
for (ViewResult.Row row : db.queryView(query)) {
map.put(row.getId(), row.getKey());
}
return map;
You will need to pre parse the output from CouchDB as there is no way to avoid returning all of that metadata with the query.
Firstly, your view needs to emit the right data (the object id, and its value).
#View(map="function(d) { if (d.someField) { emit(d.id, d.someField); } }", name = "someField")
The form of the reply is a JSON object String => Object. I would start by mapping the entire reply to this, then selecting the object with the key "rows" which is a JSON Array. Each element in this array is another JSON Object with keys "id", "key", "value". You will then need to map each of these objects to a key value pair in your output.
public Map<String, String> getSomeFields()
throws JsonParseException, JsonMappingException, IOException {
ViewQuery q =
new ViewQuery().designDocId("_design/" +
entity.getSimpleName()).viewName("someField");
String queryRresult =
StreamUtils.inputStreamAsString(db.queryForStream(q), false);
TypeReference<Map<String, Object>> mapTypeRef =
new TypeReference<Map<String,Object>>() {};
TypeReference<List<Map<String,String>>> rowsTypeRef =
new TypeReference<List<Map<String,String>>>() {};
// Map of the top level results which includes the couch meta and the
// rows. We have to use object, because Each value is of a different
// type (string, ints, json objects)
Map<String,Object> topResultMap =
mapper.readValue(queryRresult, mapTypeRef);
// Once we have the top level result, cast the value for key "rows" as
// String, and parse it as a rows type, which is a list of maps.
List<Map<String,String>> rows =
mapper.readValue((String) topResultMap.get("rows"), rowsTypeRef);
// Finally iterator over that list pulling out the id and the value in
// the key and value for the results
Map<String,String> results = new HashMap<String,String>();
for (Map<String,String> row : rows)
results.put(row.get("id"), row.get("value"));
// And return them
return results;
}
Lastly, you need to make sure you don't have a reduce part of your CouchDB view. If you do, you must pass "reduce=false" through to couch.