如何在java中的嵌套映射中为多个条目使用单个键

时间:2014-06-06 07:02:02

标签: java hashmap nested

我有一个问题,使用嵌套地图可能不是理想的解决方案,但需要一些反馈

这是存在的仿制药结构,其中水果,蔬菜,玩具是地图中的关键,而地图又有另一个地图,其中新鲜,非新鲜,腐烂是地图的关键" b"

       private Map<String, Commodity> Comm = new HashMap<String, Commodity>();
       for (Map.Entry<String, Map<String, Object>> e : this.entrySet()) {
          Comm.put(e.getKey(), getCommodity(e.getValue(), e.getKey()));
        }

        private Commodity getCommodity(Map<String, Object> m, String section) {
           return new Commodity(m, section);
        }


  Fruit=> Fresh=>object
          notFresh=>object
          rotten=>object

  Vegetable=> fresh=> object
             notfresh=>object
             rotten=>object
  Toys=> fresh=>object
        notfresh=>object
        rotten=>object

然而,我需要引入另一个名为&#34; season&#34;如果提到商品的季节,那么商品会在季节之内出现,否则就像之前提到的那样。

   i.e 
  Fruit=> winter =>Fresh=>object
                  notFresh=>object
                  rotten=>object

  Vegetable=> fresh=> object
              notfresh=>object
              rotten=>object

  Toys=> summer => fresh=>object
                   notfresh=>object
                   rotten=>object 

所以在这种情况下,水果和玩具有一个季节提到,在这种情况下,它需要在冬天看水果和夏天玩具。我怎样才能在java中实现这个复杂的地图结构

3 个答案:

答案 0 :(得分:1)

你是对的,“可能不是理想的解决方案”。映射是保存密钥和值的机制。如果您愿意,可以使用简单的映射。它们不是像你想要的那样构建复杂的数据结构。正如你自己看到的,它变得非常复杂和奇怪。所以不要这样做!

改为创建自己的课程。类是生​​成数据结构的Java方法。首先,草拟数据的外观:

  • 您有一个课程,其中包含您的所有产品(我们称之为shop
  • 这个商店有不同的类别(玩具,蔬菜)
  • 每个类别都有一个或多个季节
  • 你有四季(可以持有产品)
  • 你有你的实际产品(例如苹果可以腐烂)

如果我错了,请纠正我,但这就是我理解你的问题的方式。如果我错了,你可以自己更正细节。

现在我们有5个要点,我们可以用它们制作5个课程。 我这样做是为了保持简短:

class Shop {
    List<Category> categories;
}

class Category {    
    String name;
    List<Season> seasons;
}

class Season {
    String name;
    List<Products> products;
}

class Product {
    String name;
    boolean isRotten;
}

现在你可以用它来一起购物:

Shop myShop = new Shop();

Category toys = new Category();
Category fruits = new Category();

myShop.categories.add(toys);
myShop.categories.add(fruits);

Season summer = new Season();

fruits.seasons.add(summer);

Product apple = new Product();
Product pineapple = new Product();
Product banana = new Product();

summer.products.add(apple);
summer.products.add(pineapple);
summer.products.add(banana);

banana.isRotten = true;

注意:

  • 您可以使用getter和setter方法执行此
  • 由于只有四季,你会创建一些静态对象来代表它们
  • 还有很多方法,这只是指向方向的快速方法

答案 1 :(得分:1)

也许您可以使用对象来表达地图的关键字。 java HashMap使用对象的hashCode进行快速比较 - 当密钥冲突时,它会在equals上回退(@see HashMap。getEntry(Object key))。

class Key {

   Item item; // fruit, toys or vegetable
   Season season; // an enum for the season

   // Constructor

   public int hashCode()
   {
       int hash = 1;
       hash *= 31 + item.hashCode();
       hash *= 31 + season.hashCode();

       return hash;
   }

   public boolean equals(Object obj)
   {
       return false; // implementing the equals too
   }
}

Map<Key, Commodity> store = new HashMap<>();
store.put(
   new Key(new Item("Fruit"), Season.FRESH),
   new Commodity("asd")
);
store.put(
   new Key(new Item("Fruit"), Season.NOT_FRESH),
   new Commodity("qwe")
);
store.put(
   new Key(new Item("Vegetable"), Season.ROTTEN),
   new Commodity("zxc")
);

答案 2 :(得分:0)

像托马斯说的那样,这不是理想的解决方案。但是,只是为了测试它,在这里你去:

我想我理解结构正确。如果没有,请建议。

 Map<String, Map<String, Map<String,Commodity>>> root = new HashMap<String, Map<String,Map<String,Commodity>>>();
     Map<String, Commodity> leaf = new HashMap<String, Commodity>();
     leaf.put("fresh", new Commodity("name1", "type1"));
     leaf.put("notFresh", new Commodity("name2", "type2"));
     leaf.put("rotten", new Commodity("name3", "type3"));
     Map<String, Map<String,Commodity>> mid = new HashMap<String, Map<String,Commodity>>();
     mid.put("summer", leaf);
     mid.put("winter", leaf);
     root.put("vegetable", mid);
     root.put("fruit", mid);

    for (Entry<String, Map<String, Map<String, Commodity>>> middle: root.entrySet()) {
         Map<String, Map<String,Commodity>> midVal= middle.getValue();
         System.out.println("Type: "+ middle.getKey());
         for (Entry<String, Map<String, Commodity>> leaves : midVal.entrySet()) {
             Map<String,Commodity> leafVal = leaves.getValue();
             System.out.println("Season: " + leaves.getKey());
             for (Entry<String, Commodity> leafValNames : leafVal.entrySet()) {
                System.out.println("key: "+ leafValNames.getKey() + "value: " + leafValNames.getValue());
            }
        }
    }

}

此输出

Type: fruit
Season: winter
key: rottenvalue: test.Commodity@8def646
key: freshvalue: test.Commodity@8def63c
key: notFreshvalue: test.Commodity@8def641
Season: summer
key: rottenvalue: test.Commodity@8def646
key: freshvalue: test.Commodity@8def63c
key: notFreshvalue: test.Commodity@8def641
Type: vegetable
Season: winter
key: rottenvalue: test.Commodity@8def646
key: freshvalue: test.Commodity@8def63c
key: notFreshvalue: test.Commodity@8def641
Season: summer
key: rottenvalue: test.Commodity@8def646
key: freshvalue: test.Commodity@8def63c
key: notFreshvalue: test.Commodity@8def641

地图如下:

root = 
{vegetable={winter={rotten=test.Commodity@8df1515, fresh=test.Commodity@8df150b, notFresh=test.Commodity@8df1510}, summer={rotten=test.Commodity@8df1515, fresh=test.Commodity@8df150b, notFresh=test.Commodity@8df1510}}}

mid = 
{winter={rotten=test.Commodity@8df1515, fresh=test.Commodity@8df150b, notFresh=test.Commodity@8df1510}, summer={rotten=test.Commodity@8df1515, fresh=test.Commodity@8df150b, notFresh=test.Commodity@8df1510}}

leaf = 
{rotten=test.Commodity@8df1515, fresh=test.Commodity@8df150b, notFresh=test.Commodity@8df1510}