I'm trying to work with Java's Junit Test. My goal is to create a hashtable as
Hashtable< String , Hashtable<String,String> > student =
new Hashtable<String, Hashtable<String, String>>();
Next, I want to add at first only the key. After that, when I have the value then add it to the key in hashtable.
Example
student.put("student1",null) ;
I tried to work with null, but during test process I get a
java.lang.NullPointerException
Is it not possible? Any ideas to how adding only the key without value?
Is it possible to add a key without a value in hashtable Java?
Short answer: No
Why?
Because it will throw and Exception if
* #exception NullPointerException if the key or value is
* <code>null</code>
And in the same source code has a validation
public synchronized V put(K key, V value) {
// Make sure the value is not null
if (value == null) {
throw new NullPointerException();
}
...
You can use a Map Instead.
HashTable is an older implementation and HashMap came as an advanced version with more capabilities. You can't call .equals() or .hashCode() on it as null isn't an object.
HashMap is a better replacement for single threaded applications or any time synchronization is not a requirement, because of the performance impact synchronization introduces. If you need a Threadsafe option you can also use ConcurrentHashMap
The documentation says that you can't:
Maps the specified key to the specified value in this hashtable.
Neither the key nor the value can be null.
The best that you can do, if you need the key, is to use an empty HashTable as the value:
student.put("student1", new Hashtable<>());
In most use cases you would not care about putting null into a HashMap. You can check which keys have a value assigned via the keySet() and treat everything else as null (since it was never assigned).
However, your question to me indicates that you need to distinguish three states: Key-Value pair, key that were never assigned a value, and keys that were explicitly assigned a null value.
Since the default HashMap does not support this behavior, you could implement your own class that implements the Map interface. It basically only wraps a HashMap, with a few important exceptions:
When you assign a value of null to a key, you put the key into a Set of "NullKeys" instead of into the HashMap.
When you retrieve a key, check whether it is in the "NullKey" Set. If yes, return null, otherwise look into the HashMap.
There are some special cases (overwriting an existing value with null etc.) but this would be the basic strategy.
(I am not sure whether this is a useful class to have other than in very specialized scenarios but it would meet your requirements.)
This question already has answers here:
Why Hashtable does not allow null keys or values?
(10 answers)
Closed 4 years ago.
I know about null key is not allowed in Hashtable because to store element in Hashtable hash code must required. But if key is null it will unable to calculate hash code for null key. But I don't understand but what is the exact reason in mind for Sun developers not to allow null value.
Someone says there is null check for value inside put method implementation and that's why it throws NullPointerException. But my question is why that null value check. Is there any specific reason behind it.
I went through lots of read but no got satisfied answer. Some one says there is ambiguity if there is null value and if you try to retrieve value using get() method it will return null and this null is because of actual value is null or key is missing that's why null and could not predict reason. So i need pin point answer with proof.
You will get NULL for value if you do
hashtable.get("key")
and "key" is not in the map, then you don't need to store null values.
If you would be able to store null, you will never know what you had: null mapping or that is a missing mapping.
Hashtable is considered legacy code. You should use HashMap and it allow null for values and also one key can be null.
EDIT
After deeper search I may have argument for such decision. Hashtable is synchronized (and HashMap isn't).
From JavaDoc:
Unlike the new collection implementations, Hashtable is synchronized. If a thread-safe implementation is not needed, it is recommended to use HashMap in place of Hashtable. If a thread-safe highly-concurrent implementation is desired, then it is recommended to use ConcurrentHashMap in place of Hashtable.
As you can see successor of Hashtable is not HashMap as I previously write but ConcurrentHashMap. I was surprised that ConcurrentHashMap does not allows null. I start digging and found this:
From the author of ConcurrentHashMap himself (Doug Lea):
The main reason that nulls aren't allowed in ConcurrentMaps (ConcurrentHashMaps, ConcurrentSkipListMaps) is that ambiguities that may be just barely tolerable in non-concurrent maps can't be accommodated. The main one is that if map.get(key) returns null, you can't detect whether the key explicitly maps to null vs the key isn't mapped. In a non-concurrent map, you can check this via map.contains(key), but in a concurrent one, the map might have changed between calls.
So maybe authors of Hashtable have the same reason as authors of ConcurrentHashMap
Having a null value is still considered a bad decision in HashMap and the new Map classes and the static factory methods in java-9 prove that:
Map.of("test", null)
will throw a NulPointerException
From Java Documentation
To successfully store and retrieve objects from a hash table, the
objects used as keys must implement the hashCode method and the equals
method
Null is not an object, so can not call .equals() or .hashCode() on it, so the Hashtable can't compute a hash to use it as a key
Hashtable containsValue(Object value) function throw NullPointerException if the value is null so for the value also not allowed null
Today i read in a book:-
"HashMap allows one null key and multiple null values in a collection."
HashMap<Object,Object> ih=new HashMap<Object,Object>();
Object o1=null;
Integer o2=null;
ih.put(o1,null);
ih.put(new Integer(2),null);
ih.put(o2,new Integer(3));
This example is putting two null object references in the map.
But the following Example is successfully compiling and running...
I cant figure out why?
"HashMap allows one null key and multiple null values in a
collection."
Allow one null key means if you keep adding null key, it will overwrite the previous values. Actually, this is true for any key in HashMap.
The bottom line is - HashMap allows only one key
e.g. if you print the size of your Hashmap it will be 2.
System.out.println("size:: "+ih.size());
What the book probably means is this:
among the possible keys of a HashMap<X, Y>, there can be a null key;
whatever the key (even null!), the value associated to this key can be null.
Therefore, it is perfectly normal that your code works. It is just that the book's text here is quite confusing.
But of course, this entirely depends on the Map implementation; some of them, such as ConcurrentHashMap, will not allow null keys or values.
In a HashMap we know when we store the key and value , actually a Map.entry object is populated where Map.entry.key is mapped to key inserted in hashMap and Map.entry.value is mapped to value inserted in hashmap . Now my question is how is the supplied key is related to supplied value in a hashmap .
I mean if my understanding is correct key is not referencing directly to the value of hashMap and hence even if this reference is made to null , it should not impact the value in hashmap getting garbage collected.
Your understanding is not correct. A key-value pair is stored as an object of a class called Map.Entry. A null key is also valid key in a HashMap, and its Hashvalue equals 0. If you specify a key as null it will store as a unique key-value pair and any more entries with null key will override the previous entry. The object inside Map.Entry.key maybe null , but it itself is being stored in an LinkedList(Bucket of Entries) of hashMap and hence will not be Garbage Collected. To remove a Object from HashMap call the .remove(key) method instead of nullifying keys and depending on GC
You understanding may be right. I suggest you to read the source code from JDK.
Actually, Hashmap or other hash collections often use a array . In java
Entry<K,V>[] table
the keys hashcode() % tableSize (just for understanding) determine which index the key stores in the table array.
Apart from the fact that HashSet does not allow duplicate values, what is the difference between HashMap and HashSet?
I mean implementation wise? It's a little bit vague because both use hash tables to store values.
HashSet is a set, e.g. {1,2,3,4,5}
HashMap is a key -> value (key to value) map, e.g. {a -> 1, b -> 2, c -> 2, d -> 1}
Notice in my example above that in the HashMap there must not be duplicate keys, but it may have duplicate values.
In the HashSet, there must be no duplicate elements.
They are entirely different constructs. A HashMap is an implementation of Map. A Map maps keys to values. The key look up occurs using the hash.
On the other hand, a HashSet is an implementation of Set. A Set is designed to match the mathematical model of a set. A HashSet does use a HashMap to back its implementation, as you noted. However, it implements an entirely different interface.
When you are looking for what will be the best Collection for your purposes, this Tutorial is a good starting place. If you truly want to know what's going on, there's a book for that, too.
HashSet
HashSet class implements the Set interface
In HashSet, we store objects(elements or values)
e.g. If we have a HashSet of string elements then it could depict a
set of HashSet elements: {“Hello”, “Hi”, “Bye”, “Run”}
HashSet does not allow duplicate elements that mean you
can not store duplicate values in HashSet.
HashSet permits to have a single null value.
HashSet is not synchronized which means they are not suitable for thread-safe operations until unless synchronized explicitly.[similarity]
add contains next notes
HashSet O(1) O(1) O(h/n) h is the table
HashMap
HashMap class implements the Map interface
HashMap is
used for storing key & value pairs. In short, it maintains the
mapping of key & value (The HashMap class is roughly equivalent to
Hashtable, except that it is unsynchronized and permits nulls.) This
is how you could represent HashMap elements if it has integer key
and value of String type: e.g. {1->”Hello”, 2->”Hi”, 3->”Bye”,
4->”Run”}
HashMap does not allow duplicate keys however it allows having duplicate values.
HashMap permits single null key and any number of null values.
HashMap is not synchronized which means they are not suitable for thread-safe operations until unless synchronized explicitly.[similarity]
get containsKey next Notes
HashMap O(1) O(1) O(h/n) h is the table
Please refer this article to find more information.
It's really a shame that both their names start with Hash. That's the least important part of them. The important parts come after the Hash - the Set and Map, as others have pointed out. What they are, respectively, are a Set - an unordered collection - and a Map - a collection with keyed access. They happen to be implemented with hashes - that's where the names come from - but their essence is hidden behind that part of their names.
Don't be confused by their names; they are deeply different things.
The Hashset Internally implements HashMap. If you see the internal implementation the values inserted in HashSet are stored as keys in the HashMap and the value is a Dummy object of Object class.
Difference between HashMap vs HashSet is:-
HashMap contains key value pairs and each value can be accessed by key where as HashSet needs to be iterated everytime as there is no get method.
HashMap implements Map interface and allows one null value as a key and multiple null values as values, whereas HashSet implements Set interface, allows only one null value and no duplicated values.(Remeber one null key is allowed in HashMap key hence one null value in HashSet as HashSet implemements HashMap internally).
HashSet and HashMap do not maintain the order of insertion while iterating.
HashSet allows us to store objects in the set where as HashMap allows us to store objects on the basis of key and value. Every object or stored object will be having key.
As the names imply, a HashMap is an associative Map (mapping from a key to a value), a HashSet is just a Set.
Differences between HashSet and HashMap in Java
1) First and most significant difference between HashMap and HashSet is that HashMap is an implementation of Map interface while HashSet is an implementation of Set interface, which means HashMap is a key value based data-structure and HashSet guarantees uniqueness by not allowing duplicates.In reality HashSet is a wrapper around HashMap in Java, if you look at the code of add(E e) method of HashSet.java you will see following code :
public boolean add(E e)
{
return map.put(e, PRESENT)==null;
}
where its putting Object into map as key and value is an final object PRESENT which is dummy.
2) Second difference between HashMap and HashSet is that , we use add() method to put elements into Set but we use put() method to insert key and value into HashMap in Java.
3) HashSet allows only one null key, but HashMap can allow one null key + multiple null values.
That's all on difference between HashSet and HashMap in Java. In summary HashSet and HashMap are two different type of Collection one being Set and other being Map.
Differences between HashSet and HashMap in Java
HashSet internally uses HashMap to store objects.when add(String) method called it calls HahsMap put(key,value) method where key=String object & value=new Object(Dummy).so it maintain no duplicates because keys are nothing but Value Object.
the Objects which are stored as key in Hashset/HashMap should override hashcode & equals contract.
Keys which are used to access/store value objects in HashMap should declared as Final because when it is modified Value object can't be located & returns null.
A HashMap is to add, get, remove, ... objects indexed by a custom key of any type.
A HashSet is to add elements, remove elements and check if elements are present by comparing their hashes.
So a HashMap contains the elements and a HashSet remembers their hashes.
A HashSet uses a HashMap internally to store its entries. Each entry in the internal HashMap is keyed by a single Object, so all entries hash into the same bucket. I don't recall what the internal HashMap uses to store its values, but it doesn't really matter since that internal container will never contain duplicate values.
EDIT: To address Matthew's comment, he's right; I had it backwards. The internal HashMap is keyed with the Objects that make up the Set elements. The values of the HashMap are an Object that's just simply stored in the HashMap buckets.
Differences:
with respect to heirarchy:
HashSet implements Set.
HashMap implements Map and stores a mapping of keys and values.
A use of HashSet and HashMap with respect to database would help you understand the significance of each.
HashSet: is generally used for storing unique collection objects.
E.g: It might be used as implementation class for storing many-to-one relation ship between
class Item and Class Bid where (Item has many Bids)
HashMap: is used to map a key to value.the value may be null or any Object /list of Object (which is object in itself).
A HashSet is implemented in terms of a HashMap. It's a mapping between the key and a PRESENT object.
HashMap is a Map implementation, allowing duplicate values but not duplicate keys.. For adding an object a Key/Value pair is required. Null Keys and Null values are allowed. eg:
{The->3,world->5,is->2,nice->4}
HashSet is a Set implementation,which does not allow duplicates.If you tried to add a duplicate object, a call to public boolean add(Object o) method, then the set remains unchanged and returns false. eg:
[The,world,is,nice]
Basically in HashMap, user has to provide both Key and Value, whereas in HashSet you provide only Value, the Key is derived automatically from Value by using hash function. So after having both Key and Value, HashSet can be stored as HashMap internally.
HashSet and HashMap both store pairs , the difference lies that in HashMap you can specify a key while in HashSet the key comes from object's hash code
HashMaps allow one null key and null values. They are not synchronized, which increases efficiency. If it is required, you can make them synchronized using Collections.SynchronizedMap()
Hashtables don't allow null keys and are synchronized.
The main difference between them you can find as follows:
HashSet
It does not allow duplicate keys.
Even it is not synchronized, so this will have better performance.
It allows a null key.
HashSet can be used when you want to maintain a unique list.
HashSet implements Set interface and it is backed by the hash table(actually HashMap instance).
HashSet stores objects.
HashSet doesn’t allow duplicate elements but null values are allowed.
This interface doesn’t guarantee that order will remain constant over time.
HashMap
It allows duplicate keys.
It is not synchronized, so this will have better performance.
HashMap does not maintain insertion order.
The order is defined by the Hash function.
It is not Thread Safe
It allows null for both key and value.
It allows one null key and as many null values as you like.
HashMap is a Hash table-based implementation of the Map interface.
HashMap store object as key and value pair.
HashMap does not allow duplicate keys but null keys and values are allowed.
Ordering of the element is not guaranteed overtime.
EDIT - this answer isn't correct. I'm leaving it here in case other people have a similar idea. b.roth and justkt have the correct answers above.
--- original ---
you pretty much answered your own question - hashset doesn't allow duplicate values. it would be trivial to build a hashset using a backing hashmap (and just a check to see if the value already exists). i guess the various java implementations either do that, or implement some custom code to do it more efficiently.
HashMap is a implementation of Map interface
HashSet is an implementation of Set Interface
HashMap Stores data in form of key value pair
HashSet Store only objects
Put method is used to add element in map
Add method is used to add element is Set
In hash map hashcode value is calculated using key object
Here member object is used for calculating hashcode value which can be same for two objects so equal () method is used to check for equality if it returns false that means two objects are different.
HashMap is faster than hashset because unique key is used to access object
HashSet is slower than Hashmap