更好的方式使用Hashtables? Java的

时间:2013-04-16 21:12:22

标签: java hash

我有一个名为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?

5 个答案:

答案 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周围使用包装类而不使用泛型,则必须自己从ObjectItem进行投射。我认为没有理由你这样做。

答案 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