2012-06-30 54 views
2

我在自学Java,我有一个包含三个类(shop,product和shelf)的简单包。商店对象包含许多货架,并且货架包含许多产品,并且在这种情况下,每个产品仅在一个货架上可用。Java - 搜索对象字段的HashSet

的产品是这样的:

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,我想按名称搜索货架,看它是否已被创建的,因此,例如,在读一本线 “香蕉,果”,它会过程:

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)算法)。

谢谢!

任何试图解决这个非常感激地接受:)

回答

4

如果你正在创建的对象的类中的HashSet举行,你必须这些类体面equals()hashCode()重写方法,那些使感觉和那一起玩的很好(对于一个人使用相同的不变的字段来确定他们的结果)。

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

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"); 
1

使用HashMap代替Set将使寻找一个名为货架琐碎:

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

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

    t_shelf shelf = shelves.get(name); 

    shelf.addProduct(product);