1 回答

TA贡献1820条经验 获得超9个赞
博士
请考虑使用哈希映射而不是哈希集。具体来说,考虑
HashMap<KeyType, Object[]>,或者,甚至更好,
HashMap<KeyType, ItemWrapper>
其中,KeyType 是项类中的字符串、整数或某种其他类型的唯一标识符,而 ItemWrapper 是用于存储相关数据的简单类。
哈希映射可能比哈希集更适合于此
您说您不想使用数组,因为您希望使用标识符而不是添加顺序的标识符进行快速检索。您还希望将商品“映射”到数量计数。哈希映射将允许您将键与值相关联,以便快速查找。
我们将从一个过于简单的实现开始,然后让它变得更好。我还将展示如何像您要求的那样使用大小为 2 的数组,即使这不是最佳方法。
我们将改进的基本实现
在过于简单的实现中,您的密钥可能是您的 Item,您的值可能是数量。例如
HashMap<Item, Integer> myHashMap = new HashMap<Item, Integer>(1400);
public int addItem(Item item, int n) {
//...
int currentCount = myHashMap.getOrDefault(item, 0);
myHashMap.put(item, n + currentCount);
//...
}
public int quantityOf(Item item) {
return myHashMap.getOrDefault(item, 0);
}
public boolean isInLocker(Item item) {
return myHashMap.containsKey(item);
//or return this.quantityOf(item) > 0;
}
(请注意,此代码依赖于自动装箱和取消装箱,但如果您愿意,可以在没有它的情况下编写。此外,您还可以调整哈希图的初始容量。初始容量为 1400,负载系数为 .75,一旦 HashMap 中出现大约 1050 个项目,它将调整大小。
这样做的麻烦在于,您需要已经拥有 Item 对象才能查找该项目,这在大多数情况下可能不切实际。(或者,至少,您需要具有相同结果的东西,并且返回为 true)。如果适用,可以在 Item 类中添加 和 。但是,如果为您提供了 Item 类,则不允许更改它(或不想更改),并且 和 不满足快速查找的需求,该怎么办?在这种情况下,您必须具有不同的键,例如 item ID 或唯一描述符(例如,如果程序中所有“铅笔”项的处理方式相同,则字符串将起作用)。hashCode()equals()@OverrideshashCode()equals()hashCodes()equals()
更强大的方法
为了让您的快速检索梦想与HashMap一起工作,您需要一种独特的方法来识别 Item 对象 - 我们将以此为关键。对于下面的示例代码,我假设标识符是字符串。您还需要一种方法将物料与数量相关联。
我建议不要使用 Object [],而是将 Item 包装在一个新的简单类中,该类同时跟踪项目及其数量。例如:
class ItemWrapper {
Item item;
int quantity;
}
(我保持了示例的简单性,但您可以根据需要将成员设为私有,添加获取者/设置者等。
这样,您的代码就更具可读性,并且需要的强制转换更少。然后,你可以将它与代码一起使用,如下所示:
HashMap<String, ItemWrapper> myHashMap = new HashMap<String, ItemWrapper>(1400);
public int addItem(Item item, int n) {
//...
ItemWrapper wrappedItem = myHashMap.get(item.uniqueID);
if (wrappedItem == null) {
wrappedItem = new ItemWrapper(item, n);
}
else {
wrappedItem.quantity += n;
}
myHashMap.put(item.uniqueID, wrappedItem);
//...
}
public int quantityOf(String itemID) {
ItemWrapper wrappedItem = myHashMap.get(itemID);
return wrappedItem == null ? 0 : wrappedItem.quantity;
}
public boolean isInLocker(String itemID) {
return myHashMap.containsKey(itemID);
//or return this.quantityOf(itemID) > 0;
}
使用数组直接回答您的问题(不是最佳方法)
在您的问题中,您询问了大小为 2 的数组。上面的方法是我的建议,但是如果必须使用数组,则可以执行如下代码所示的操作:
HashMap<Item, Object[]> myHashMap = new HashMap<Item, Object[]>(1400);
public int addItem(Item item, int n) {
//...
Object[] itemBundle = myHashMap.get(item.uniqueID);
if (itemBundle == null) {
itemBundle = new Object[2];
itemBundle[0] = item;
itemBundle[1] = new Integer(n);
}
else {
itemBundle[2] = new Integer((Integer)itemBundle[2] + n);
}
myHashMap.put(item.uniqueID, itemBundle);
//...
}
public int quantityOf(String itemID) {
return myHashMap.getOrDefault(itemID, 0);
}
public boolean isInLocker(String itemID) {
return myHashMap.containsKey(itemID);
//or return this.quantityOf(itemID) > 0;
}
道明
你关于测试驱动开发的“额外问题”可能最好作为一个单独的问题来研究。您是否在询问如何在概念上接近TDD,或者如何实际编写用于测试的代码?无论哪种方式,您都可以通过搜索堆栈溢出的现有内容找到很好的答案。
添加回答
举报