我有一个名为Stored的类,它将保存我的Hashtable,它将保存Class“Item”中的对象。我之前从未使用过Hashtables或者真的非常了解它们,但是从我的窥探中看来似乎有很多不同的方法来使用它们。所以我的问题是,哪个是最好的?为什么?
CODE UPDATED
我的程序中有这个...
public class Store implements Serializable{
Hashtable<String, Item> store = new Hashtable<String, Item>();
}
我也见过这个......
Hashtable<Object> store = new Hashtable<Object>();
一个比另一个好吗?
另外,作为参考,我的Item Class Objects将有2个字符串,并且int作为变量,如果这一点很重要。
我也想知道这些Hashtables是否需要任何构造函数或者是否需要大小初始化?我在一些例子中看到过,而在其他例子中没有看到过。据我所知,它们会自动增加尺寸......最重要的是什么?
编辑:
我的主要内容......
Store store = new Store();
Item item1 = new Item();
item1.setProductName("Paper Towel Roll");
item1.setBarCode("111222333444");
item1.setQuantity(1);
store.put("111222333444", item1);
Item item2 = new Item();
item2.setProductName("Paper Towel Roll");
item2.setBarCode("111222333444");
item2.setQuantity(1);
store.put("111222333444", item2);
Item item3 = new Item();
item3.setProductName("Paper Towel Roll");
item3.setBarCode("111222333444");
item3.setQuantity(1);
store.put("111222333444", item3);
Item item4 = new Item();
item4.setProductName("Paper Towel Roll");
item4.setBarCode("111222333444");
item4.setQuantity(1);
store.put("111222333444", item4);
我的put()调用不起作用。为什么我无法访问我的HashTable?
答案 0 :(得分:2)
您看到的内容与Hashtables无关。它是泛型语言的一个特征。它允许您限制与您定义的对象一起使用的类型,而不必使用新的类。
典型用法是
Hashtable<Integer, Item> store = new Hashtable<Integer, Item>();
这确保在使用您定义的类型的操作中,只有在类型匹配时才接受它。
所以,
store.put(1, new Ítem());
可行,但
store.put(2, new String("Hello world"));
会失败,因为String
不是Item
的子类。
如果你不使用泛型,v.g。旧式Java
Hashtable store = new Hashtable();
它可以工作,但编译器不会用
检测到任何失败 store.put(2, new String("Hello world"));
所以你失去了(通常)有用的控制。
答案 1 :(得分:0)
如果你想使用泛型,你可以这样做:
Hashtable<Key,Item> store = new Hashtable<Key, Item>();
如果您在Hashtable
周围使用包装类而不使用泛型,则必须自己从Object
到Item
进行投射。我认为没有理由你这样做。
答案 2 :(得分:0)
关于初始化的大小:
确实,集合(Hashtable)在向它们添加项目时会动态增加
初始容量是将在内存中分配的项目数。如果你不给这个数字,初始容量会得到一些默认值(我认为11)。
随着Hashtable的增加,需要分配更大的存储空间。重新分配需要一些CPU工作,并且可能会降低执行中的程序速度。
因此,通过正确使用初始容量数,您可以省去一些不必要的CPU周期,但在今天的计算机上,除非您正在进行一些非常大的插入,否则我认为这不重要。
答案 3 :(得分:0)
第二个示例使用Generics,它允许您在编译时检查类型安全性并减少对强制转换的需求,通常被认为是更好的选择。对于Hashtable构造函数,在大多数情况下,您可以使用no arg构造函数创建具有默认加载因子0.75和初始容量11的Hashmap。加载因子指定何时将哈希表的所有元素复制到更大的数组。当元素数量超过负载系数*容量(内部数组大小)时,就会发生这种情况。其他构造函数允许您指定载荷因子和初始容量。还有一个构造函数可以从现有Map构建哈希表。您应该考虑在非线程应用程序中使用HashMap而不是Hashtable以获得更好的性能。此外,从这行代码:
Hashtable<Object> store = new Hashtable<Object>();
我认为您打算使用HashSet,因为您只存储值,而不是键值对。
答案 4 :(得分:-1)
您想使用泛型:
public class Store implements Serializable{
Hashtable<Key, Item> store = new Hashtable<Key,Item>();
}
这确保只有Item
个对象(以及正确的子类对象)可以放在Hashtable
中,这意味着您必须在使用此哈希表的任何地方进行更少的检查。
Key
可以是您用来引用商品的任何内容;它可能是Integer
,或String
或其他对象。
这可以防止发生以下情况:
public class Item {
public String blah;
...
public void printThisString() {
System.out.println(blah);
}
...
}
...
Hashtable store = new Hashtable();
Item item = new Item();
item.blah = "Hello world!";
store.put("FirstKey",item);
store.put("SecondKey","Hello world!");
...
store.get("FirstKey").printThisString();//Works fine!
store.get("SecondKey").printThisString();//Fails because String does not have a printThisString method.
这迫使有人插入哈希表来考虑他们正在做什么:
Hashtable<String, Item> store = new Hashtable<String,Item>();
Item item = new Item();
item.blah = "Hello world!";
store.put("MyKey",item);
store.put("SecondKey","Three tears for all the souls!");//Will not compile because a String isn't an Item
...
store.get("MyKey").printThisString();//We can therefore be sure what is returned is an Item
代码更新
解决您的代码更新问题:
Store<String, Item> store = new Store<String, Item>();
Item item1 = new Item();
item1.setProductName("Paper Towel Roll");
item1.setBarCode("111222333444");
item1.setQuantity(1);
store.put("111222333444", item1);//note that since it's quoted the key is a String