开发者

Need help with java map and javabean

开发者 https://www.devze.com 2022-12-23 06:42 出处:网络
I have a nested map: Map<Integer, Map<Integer, Double>> areaPrices = new HashMap<Integer, Map<Integer, Double>>();

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消