Java - 搜索对象字段的HashSet

时间:2012-06-30 19:54:04

标签: java oop hashset

我正在自学Java,我有一个简单的包,有三个类 - 商店,产品和货架。商店对象包含许多货架,货架包含许多产品,在这种情况下,每个产品仅在一个货架上提供。

产品如下所示:

public class t_product {
    private t_shelf shelf;
    private String name;
}

架子看起来像这样:

public class t_shelf {    
    private Set<t_product> products = new HashSet<>();
    private String name;
}

商店对象如下所示:

public class t_shop {    
    private Set<t_shelf> shelves = new HashSet<>();
}

我还有一组功能,可以从架子上添加或删除产品。

myshelf.addProduct(myproduct);

将设置myproduct.shelf = myshelf,并将myproduct添加到myshelf.products。这很好,并很好地处理这种关系。类似的功能链接商店和货架。

继续讨论问题

我有一个.csv存储:

Product   |   Shelf
----------------------
Hats      |   Headwear
Helmets   |   Headwear
Socks     |   Footwear
Apples    |   Fruit
Bananas   |   Fruit
Oranges   |   Fruit

解析.csv时,我想按名称搜索这个架子,看它是否已经被创建,所以,例如,在阅读“Bananas,Fruit”这一行时,它会处理:

if (!myshop.getShelfByName("Fruit")){
       myshop.addShelf(new t_shelf("Fruit"));
   }
myshop.getShelfByName("Fruit").addProduct("Bananas"); //Constructors accept the name as a parameter.

我的问题是:

是否有更简洁的getShelfByName(String name)实现,而不是简单地遍历HashSet并针对每个项目检查名称? (想要避免O(N)算法)。

谢谢!

任何解决这个问题的尝试都非常感激地接受了:)

3 个答案:

答案 0 :(得分:4)

如果您要创建要在HashSet中保存的对象类,则必须为这些类提供正确的equals()hashCode()覆盖方法,这些方法是有意义的,一起玩得很好(一个人使用相同的不变字段来确定他们的结果)。

至于你的具体问题,考虑把东西放在HashMaps而不是HashSets中,因为你可以通过它的键轻松找到对象。

答案 1 :(得分:2)

您应该将货架存放在HashMap中(密钥应该是货架的名称)。 你将有一个O(1)算法。

public class t_shop {    
    private Map<String, t_shelf> shelves = new HashMap<String, t_shelf>();

    public void addShelve(t_shelf) {
        shelves.put(t_shelf.getName(), t_shelf);
    }

    public tshelf getShelfByName(String name) {
        return shelves.get(name);
    }
}


t_shelf shelf = myshop.getShelfByName("Fruit");
if (null != shelf){
    shelf = new t_shelf("Fruit");
    myshop.addShelf(shelf);
}
shelf.addProduct("Bananas");

答案 2 :(得分:1)

使用HashMap代替Set会使寻找一个命名的架子变得微不足道:

private Map<String, t_shelf> shelves = new HashMap<>();

// ...
if (shelves.contains(name)) {

    t_shelf shelf = shelves.get(name);

    shelf.addProduct(product);