I have the following class and that provide entity name with key and val of HashMap:
import java.util.LinkedHashMap;
public class ObjectStructure {
private String entityName;
private LinkedHashMap<String, String> keyVal;
public String getEntityName() {
return entityName;
}
public void setEntityName(String entityName) {
this.entityName = entityName;
}
public LinkedHashMap<String, String> getKeyVal() {
return keyVal;
}
public void setKeyVal(LinkedHashMap<String, String> keyVal) {
this.keyVal = keyVal;
}
}
I have also list as follows
private static List<ObjectStructure> JsonObj = new ArrayList<ObjectStructure>();
Since I'm getting the JSON object which list I need method that provide list by name
(i.e. entityName can have many entries and I want for specific entity get
the list of the respective data). I guess I need to build new class for it but I'm not sure how to design it, any ideas?
You could work with a different map:
Map<String, Map<String,String>> entities;
The key of the outer map would be the entityName, the inner Map is the collection of key/value pairs. To get the key/value pairs for a named entity, simply do:
Map<String, String> keyValueMap = entities.get("MyEntity");
I'm not quite sure what you are asking,
but if your asking how to return a certain ObjectStructure by entityName from the arraylist,
then just loop through the ArrayList and compare your searchString with each ObjectStructure's entityName.
If your looking for a value inside of the ObjectStructure inside of the ArrayList then
search the ArrayList for the right ObjectStructure. Once found, search the ObjectStructure for the key you are looking for.
Related
I've looked at so many examples but can't quite grasp this.
I need to create a method that inserts new values into already populated lists within my hashmap. I can't for the life of me figure out how to do. Can anyone help as well as explain how it works?
I've already created methods that populate the maps etc. I just can't figure out how to create a method that inserts just values for particular keys.
import java.util.*;
public class Singles
{
// instance variables - replace the example below with your own
private Map<String, List<String>> interests;
/**
* Constructor for objects of class Singles
*/
public Singles()
{
// initialise instance variables
super();
this.interests = new HashMap<>();
}
}
This is a multi-map.
public class MultiMap {
private Map<String, List<String>> multiMap = new HashMap<>();
public void put(String key, String value) {
List<String> values = (this.multiMap.containsKey(key) ? this.multiMap.get(key) : new ArrayList<>());
values.add(value);
this.multiMap.put(key, values);
}
}
I am trying to store 3 values. The last value is an object which can be accessed by XID. The main ID can be used to get the object.
I can think of two ways to implement this. Which would be a better approach? Also, which is better in terms of thread-safe and faster lookups?
Create a class and add it to the HashMap.
public class TestMap {
private int xid;
private XObject xobject;
public TestMap(int xid, XObject xobject) {
this.xid = xid;
this.object = object;
}
public int getXid() { return xid; }
public XObject getXOBject { return xobject; }
}
map.put(ID, new TestMap(xid, xobject));
Create a nested HashMap
HashMap<id, HashMap<xid, XObject>> map = new HashMap<>();
map.put(id, new HashMap() {{ put(xid, xobject); }} );
When you access it by the main ID, do you first need to specify the XID?
I'm assuming that you do not. In this case, I would make two Maps.
One is a Map<id,object> which you use when looking up by id. The second is a Map<xid,object> which you use when looking up by xid.
I am trying to parse a JSON object which consists of an Array of Customer objects. Each customer object contains a number of key/value pairs:
{
"Customers":
[
{
"customer.name": "acme corp",
"some_key": "value",
"other_key": "other_value",
"another_key": "another value"
},
{
"customer.name": "bluechip",
"different_key": "value",
"foo_key": "other_value",
"baa": "another value"
}
]
}
The complication is that the keys are not known to me in advance. A second complication is that the keys contain periods (.) that mean that even when I have tried to map them to a field, it fails.
I have been trying to map these to a Customers class:
Customers data = new Gson().fromJson(responseStr, Customers.class);
which looks like this:
public class Customers {
public List<Customer> Customers;
static public class Customer {
public List<KeyValuePair> properties;
public class KeyValuePair {
String key;
Object value;
}
}
}
My problem is that in when I load this class from the JSON, my Customers list populates, but their properties are null. How can I make GSON deal with the fact that I don't know the key names?
I have tried various other approaches including putting a HashMap in the Customer class, in place of the KeyValuePair class.
A different approach is that, you can create a Map of key values from the JSON and then look for the values, since the keys are not known
Gson gson = new Gson();
Type mapType = new TypeToken<Map<String,List<Map<String, String>>>>() {}.getType();
Map<String,List<Map<String, String>> >map = gson.fromJson(responseStr, mapType);
System.out.println(map);
Customers c = new Customers();
c.setCustomers(map.get("Customers"));
System.out.println(c.getCustomers());
Modify your Customers class like this
public class Customers {
public List<Map<String, String>> customers;
public List<Map<String, String>> getCustomers() {
return customers;
}
public void setCustomers(List<Map<String, String>> customers) {
this.customers = customers;
}
}
I have a list of HashMaps. Each HashMap consists of several kay-value pairs and everything comes as a string. I am storing all the hashmaps inside an arraylist. Now I need to sort the arraylist based on the key inside the hashmap.
Here is my sample data:
{
"productID":"5643",
"productName":"Apple - iPod touch",
"outsidePrice":"189.99",
"merchantID":"134439",
"ourPrice":"184.99",
"storeName":"Ebay",
}
{
"productID":"3243",
"productName":"Apple - iPad",
"outsidePrice":"389.99",
"merchantID":"54439",
"ourPrice":"384.99",
"storeName":"Apple",
}
I am storing this data inside this structure.
ArrayList<HashMap<String, String>> data_list = new ArrayList<HashMap<String, String>>();
I have a huge list of items like this. Now I need to sort the arraylist based on the productName, Price, storeName, productID fields inside the hashmap.
I recommend that you use a custom product class to do this for you. It will ultimately make your code easier to maintain and more robust, IMHO.
How about this?
A class to represent your data:
class Product{
public string productId;
public string productName;
public BigDecimal outsidePrice;
public int merchantId;
public BigDecimal ourPrice;
public string storeName;
// whatever constuctors you need
}
A List of your products:
List<Product> products;
Now define a Comparator to sort, one for each field that you need to sort on. Here is an example for productId.
public class ProductProductIdComparator implements Comparator<Product>{
#Override
public int compare(Product product1, Product product2) {
if (product1.productId > product2.productId){
return +1;
}else if (product1.productId < product2.productId){
return -1;
}else{
return 0;
}
}
}
And finally, a Collections sort which accepts a comparator as an argument:
Collections.sort(products, new ProductProductIdComparator());
The Collections class provides a utility method for sorting a list in place, using a Comparator.
final List<Map<String, String>> dataList = new ArrayList<HashMap<String, String>>(4);
Collections.sort(dataList, new Comparator<Map<String, String>>() {
#Override
public int compare(final Map<String, String> map1, final Map<String, String> map2) {
// Get fields from maps, compare
}
}
You can use arrays.sort() to achieve this in short, at some minor memory cost.
HashMap[] result = Arrays.sort(list.toArray(), new Comparator() {
public void compare(Object o1, Object o2) {
HashMap<String, String> a = (HashMap<String, String>)o1;
HashMap<String, String> b = (HashMap<String, String>)o2;
// return value as per contract of Comparator.compare() doing whatever comparisons you need.
}
public boolean equals(Object obj) { return this == obj; }
});
I have a nested map:
Map<Integer, Map<Integer, Double>> areaPrices = new HashMap<Integer, Map<Integer, Double>>();
and this map is populated using the code:
while(oResult.next())
{
Integer areaCode = new Integer(oResult.getString("AREA_CODE"));
Map<Integer, Double> zonePrices = areaPrices.get(areaCode);
if(zonePrices==null)
{
zonePrices = new HashMap<Integer, Double>();
areaPrices.put(areaCode, zonePrices);
}
Integer zoneCode = new Integer(oResult.getString("ZONE_CODE"));
Double value = new Double(oResult.getString("ZONE_VALUE"));
zonePrices.put(zoneCode, value);
myBean.setZoneValues(areaPrices);
}
I want to use the value of this Map in another method of the same class. For that I have a bean.
How do I populate it on the bean, so that I can get the ZONE_VALUE in this other method
In my bean I added one new field as:
private Map<Integer, Map<Integer, Double>> zoneValues;
with getter and setter as:
public Map<Integer, Map<Integer, Double>> getZoneValues() {
return zoneValues;
}
public void setZoneValues(Map<Integer, Map<Integer, Double>> areaPrices) {
this.zoneValues = areaPrices;
}
What I am looking for to do in the other method is something like this:
Double value = myBean.get(areaCode).get(zoneCode);
How do I make it happen :(
I would like to suggest a different, hopefully more readable solution:
public class PriceMap {
private Map<Integer, Map<Integer, Double>> priceMap =
new HashMap<Integer, Map<Integer, Double>>();
// You'd use this method in your init
public Double setPrice(Integer areaCode, Integer zoneCode, Double price) {
if (!priceMap.containsKey(zoneCode)) {
priceMap.put(zoneCode, new HashMap<Integer, Double>());
}
Map<Integer, Double> areaMap = priceMap.get(zoneCode);
areaMap.put(areaCode, price);
}
public void getPrice(Integer areaCode, Integer zoneCode) {
if (!priceMap.containsKey(zoneCode)) {
// Eek! Exception or return null?
}
Map<Integer, Double> areaMap = priceMap.get(zoneCode);
return areaMap.get(areaCode);
}
}
I think this is a better, more readable abstraction which, very importantly, makes it easier for you or someone else to read after a few months.
EDIT Added get get
If you're stuck with a get(areaCode).get(zoneCode) (order reversed), but myBean is entirely yours, you could do something like:
public class MyBean {
// I suppose you have this already
private final Map<Integer, Map<Integer, Double>> priceMap =
new HashMap<Integer, Map<Integer, Double>>();
private class LooksLikeAMap implements Map<Integer, Double> {
private Integer areaCode = areaCode;
public LooksLikeAMap(Integer areaCode) {
this.areaCode = areaCode;
}
public Double get(Object zoneCode) {
if (!priceMap.containsKey(zoneCode)) {
// Eek! Exception or return null?
}
Map<Integer, Double> areaMap = priceMap.get(zoneCode);
return areaMap.get(areaCode);
}
// Implement other methods similarly
}
public Map<Integer, Double> get(Integer areaCode) {
return new LooksLikeAMap(areaCode);
}
}
OK, programming in a HTML textarea is not my strong suit, but the idea is clear.
Make some Map like structure backed by the complete data set, and initialize that
Map structure with the required AreaCode.
If the idea is not clear, post a comment fast as it's late here:)
EDIT
I am an idiot. I thought the data was zone first, then area while the get should be area first, then zone. In this case the Map already has the right structure, first area then zone, so this is not necessary. The get-get is by default if you make
public MyBean {
public Map<Integer, Double> get(Integer areaCode) {
return data.get(areaCode);
}
}
To start with, all you need is
myBean.getZoneValues(areaCode).get(zoneCode);
the while loop has an annoyance, you need to call myBean.setZoneValues(areaPrices);
out side the while loop
You can't directly control the second get() call because you have a nested Map, you'll need to return the appropriate nested Map to be able to do what you want. A getter like this should do it:
public Map<Integer, Double> get(Integer areaCode) {
return zoneValues.get(areaCode);
}
So when the client code calls get(areaCode) a map will be returned that they can then call get(zoneCode) on.
I'd suggest that you refactor to eliminate the nested Maps though, because you can't stop client code from changing the returned Map, the code is tough to read and you'll have problems if you want to add any more functionality - imagine that you want to provide a String description of an area code in future.
Something like a Map<Integer, AreaCode> where AreaCode is an object that contains what you currently have as a nested Map might be a good place to start.