我正在自学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)算法)。
任何解决这个问题的尝试都非常感激地接受了:)
答案 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);