3

I have a class named Stored that will hold my Hashtable, which will hold Objects from the Class "Item". I have never used Hashtables before or really know all that much about them, but from my snooping around it seems as if there is a lot of different ways to use them. So my question is, which is the best? And why?

CODE UPDATED

I have in my program this...

public class Store implements Serializable{

Hashtable<String, Item> store = new Hashtable<String, Item>();

}

I have also seen this...

Hashtable<Object> store = new Hashtable<Object>();

Is one better than the other?

Also for reference my Item Class Objects will have 2 strings and an int as variables if that matters at all.

I'm also wondering if these Hashtables should need any constructor or maybe a size initialization? I have seen that in some examples and not in others. As far as I know they increase in size automatically so...whats the point?

EDIT:

I have this in my main...

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

My put() calls don't work. Why can't I access my HashTable?

Sherifftwinkie
  • 391
  • 1
  • 13
  • 21
  • 1
    The second is called Generics and yes, it is better. Though the generic definition on Hashtable requires the key type and the value type: `Hashtable`. – Lucas Apr 16 '13 at 21:14
  • 2
    Related: [Differences between HashMap and Hashtable?](http://stackoverflow.com/questions/40471/differences-between-hashmap-and-hashtable). – Paul Bellora Apr 16 '13 at 21:14
  • 'Best' is a highly context-sensitive term. – Kenogu Labz Apr 16 '13 at 21:14
  • Of course, a lot of folks here will tell you never to use Hashtable, always HashMap or some other Map class. But the reasons for that are somewhat esoteric. – Hot Licks Apr 16 '13 at 21:39
  • Note that if your Hashtable (or HashMap) is contained wholly within a wrapper class and cannot be accessed except by methods of that wrapper class then the "generic" stuff essentially does nothing for you that you're not already doing. – Hot Licks Apr 16 '13 at 21:40
  • So I want to use Hashtable store = new HashTable();? – Sherifftwinkie Apr 16 '13 at 22:51
  • You have to write put() method in Store class, which internally calls put() on member 'store'. – Kishore Apr 17 '13 at 07:10

5 Answers5

2

What you see is not related to Hashtables. It is a feature of the language called Generics. It allows you to restrict the type to use with the object you define, without having to créate a new Class.

A typical usage would be

 Hashtable<Integer, Item> store = new Hashtable<Integer, Item>();

That ensures that, in operations that use the type defined by you, only it is accepted if the type matches.

So,

 store.put(1, new Ítem());

would work, but

 store.put(2, new String("Hello world"));

would fail because String is not a subclass of Item.

If you do not use generics, v.g. old style Java

 Hashtable store = new Hashtable();

it would work, but the compiler won't detect any failure with

 store.put(2, new String("Hello world"));

so you lose (usually) useful controls.

SJuan76
  • 24,532
  • 6
  • 47
  • 87
  • 1
    And it would fail at _compile_ time, so you can catch errors long before running your code... – Lucas Apr 16 '13 at 21:18
  • Yes, as Lucas said, all this is done at compile time. At runtime it does not check for generics, because there was no way to introduce it without breaking backwards compatibility. – SJuan76 Apr 16 '13 at 21:20
  • @SJuan76 - Actually, it probably could have been done without breaking compatibility (not that I would have liked to see this), but internal Java politics got in the way. An amazing number of easily upward-compatible changes were bypassed, while several incompatible ones were implemented. (I get the impression that it was quite the Peyton Place at times.) – Hot Licks Apr 16 '13 at 21:43
0

If you want to use generics you can do it like this:

Hashtable<Key,Item> store = new Hashtable<Key, Item>();

If you go for a wrapper class around a Hashtable without the use of generics , you will have to do the casting from Object to Item yourself. I see no reason why you would do that.

DeltaLima
  • 5,864
  • 1
  • 16
  • 32
0

Regarding size in initialization:
It is true that Collections (Hashtable as well) increase dynamically as you add items to them.
Initial capacity is the number of items that will be allocated in memory. If you don't give this number, initial capacity gets some default value (11 I think). As the Hashtable increases, a larger storage will need to be allocated. Reallocation requires some CPU work and can slow down the program in execution. So, by using the initial capacity number correctly, you can spare yourself some unnecessary CPU cycles, but on today's computers, unless you are doing some really really large insertions, I don't think it really matters.

Maggie
  • 7,823
  • 7
  • 45
  • 66
0

The second example uses Generics which allows you to check type safety at a compile time and reduces the need for casts and is generally considered a better option. As for Hashtable constructors, for most cases you can use the no arg constructor which creates a Hashmap with default load factor 0.75 and innitial capacity 11. Load factor specifies when all elements of the hashtable will be copied to a bigger array. It happens when the number of elements exceeds load factor * capacity (internal array size). Other constructors allow you to specify load factor and innitial capacity. There are also a constructor to build a hashtable from existing Map. You should consider using HashMap instead of Hashtable in non-threaded applications for better performance. Also, from this line of code:

Hashtable<Object> store = new Hashtable<Object>();

I think you intended to use HashSet, because you store only values, not key - value pairs.

luke657
  • 826
  • 2
  • 11
  • 28
-1

You want to use generics:

public class Store implements Serializable{
  Hashtable<Key, Item> store = new Hashtable<Key,Item>();
}

This ensures that only Item objects (and properly subclasses objects) can be placed in your Hashtable, which means you have to do less checking in any place where you use this hashtable.

Key can be anything you're using to reference your item; it might be Integer instead, or a String or some other object.

This prevents the following from happening:

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.

This forces someone inserting into the hashtable to think about what they're doing:

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

CODE UPDATE

To address your code update:

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
Nathaniel Ford
  • 20,545
  • 20
  • 91
  • 102
  • I can't access my hashTable for my main, I am trying to call put() but it says I need to create the method. – Sherifftwinkie Apr 17 '13 at 01:46
  • You mean if you use generics? Which method is it saying you need to create? See my update and see if it works. – Nathaniel Ford Apr 17 '13 at 03:22
  • Yeah see what you have, that worked, but what is the point of the Store class if the HashTable is in my main? – Sherifftwinkie Apr 17 '13 at 03:27
  • The description provided for the Store class states it "..uses a hash table to store names information about items in a store in a hash table for easy lookup." It will also have, methods add, remove, and find. – Sherifftwinkie Apr 17 '13 at 03:31
  • So, Generics make such things generally antiquated: that's the point of generics. It reduces the amount of code you need to write. – Nathaniel Ford Apr 17 '13 at 05:20