In Javascript we can store values in array like
var arr=[];
arr["name"]="test";
arr["value"]="result";
console.log(arr["name"]);
above mentioned array is storing values like key value pair,my question is this we can achieve in java without using hashmap ? so that we can get value by key in java
I mean you could achieve it that way, but it is much less efficient. Searching an array for a specific value will be of O(n) complexity while hashmaps only take O(1) in the best case scenario (with no chaining).
It's not possible. Arrays are Integer Index based in Java.
HashMap is specifically designed for that purpose.
Related
I have an object that is identified by 3 fields. One them is a String that represents 6 hex bytes, the other two are integers of not more than 1 bytes each. This all summed up is 8 bytes of data, which fits in a 64 bit integer.
I need to map these objects for fast access, and I can think of two approaches:
Use the 3 fields to generate a 64 bit key used to map the objects. This however would mean parsing the String to Hex for every access (and there will a lot of accesses, which need to be fast).
Use 3 HashMap levels, each nested inside the next, to represent the 3 identifying fields.
My question is which of these approaches should be the fastest.
Why not use a MultiKeyMap?
This might be not related to your question.
I have a suggestion for you.
Create an object with the 3 attributes that will form the key. Use the object has the key because it will be unique.
Map<ObjectKey,Object> map = new HashMap<>();
This makes sense for your use case? If you can add a bit more explanation maybe I can go further in suggest you possible solutions.
EDIT: You can override the equals and do something using this kind of logic:
#Override
public boolean equals(Object obj) {
if (!(obj instanceof Key))
return false;
ObjectKey objectKey= (Key) obj;
return this.key1.equals(objectKey.key1) && this.key2.equals(objectKey.key2) &&
...
this.keyN.equals(objectKey.keyN)
}
I would take the following steps:
Write it in the most readable way first, and profile it.
Refactor it to an implementation you think might be faster, then profile it again.
Compare.
Repeat.
Your key fits into a 64-bit value. Assuming you will build the HashMap in one go and then read from it multiple times (using it as a lookup table), my hunch is that using a Long type as the key of your HashMap will be about as fast as you can get.
You are concerned about having to parse the string as a hex number every time you look up a key in the map. What's the alternative? If you use a key containing the three separate fields, you will still have to parse the string to calculate its hash code (or, rather, the Java API implementation will calculate its hash code by parsing the string contents). The HashMap will not only call String.hashCode() but also String.equals(), so your string will be iterated twice. By contrast, calculating a Long and comparing it to the precalculated keys in the HashMap will consist of iterating the string only once.
If you use three levels of HashMap, as per your second suggestion, you will still have to calculate the hash code of your string, as well as having to look up the values of all three fields anyway, so the multi-level map doesn't give you any performance advantage.
You should also experiment with the HashMap constructor arguments to get the most efficiency. These will determine how efficiently your data will get spread into separate buckets.
I was trying to implement a trie and read in an example implementation that it would be more space efficient to use a small array of size 26 to store the children because then you wouldn't have to waste space with a HashMap (the code was in Java, if that makes a difference)
But wouldn't a map be more space efficient since you don't necessarily need to store all 26 values? Or is a HashMap object that contains Character objects as keys just more space because a simple int[] type does not use extra space in the background that the implementation for these more complex objects would use?
Just wanting to check if maybe this person was mistaken or if there's some overhead involved in using object types like HashMap that I should be aware of.
A hashmap stores keys and values, so if you were to implement a trie using a hashmap, you would be storing not only the values, but also the keys. If you use an array, then the key is actually the index of the value in the array, so you do not have to store it anywhere.
Besides that, hashmaps are less space efficient than arrays because they always have a load factor which is smaller than one, which is the same as saying that they keep more entries allocated than necessary due to the way they work. I am not expanding on this, because it is not related to your issue, but if you are curious, search for hashmap load factor.
This is a classic programming compromise. In this case, using a HashMap will take more space, but that may be a price you're willing to pay for improved performance. Or it might not. Depends on your problem.
In Java.
How can I map a set of numbers(integers for example) to another set of numbers?
All the numbers are positive and all the numbers are unique in their own set.
The first set of numbers can have any value, the second set of numbers represent indexes of an array, and so the goal is to be able to access the numbers in the second set through the numbers in the first set. This is a one to one association.
Speed is crucial as the method will have to be called many times each second.
Edit: I tried it with SE hashmap implementation, but found it to be slow for my purposes.
There's an article, devoted to this problem (with a solution): Implementing a world fastest Java int-to-int hash map
Code can be found in related GitHub repository. (Best results are in class IntIntMap4a.java )
Citation from the article:
Summary
If you want to optimize your hash map for speed, you have to do as much as you can of the following list:
Use underlying array(s) with capacity equal to a power of 2 - it will allow you to use cheap & instead of expensive % for array index
Do not store the state in the separate array - use dedicated fields for free/removed keys and values.
Interleave keys and values in the one array - it will allow you to load a value into memory for free.
Implement a strategy to get rid of 'removed' cells - you can sacrifice some of remove performance in favor of more frequent get/put.
Scramble the keys while calculating the initial cell index - this is required to deal with the case of consecutive keys.
Yes, I know how to use citation formatting. But it looks awful and doesn't handle bullet lists well.
The structure you are looking for is called an associative array. In computer science, an associative array, map, symbol table, or dictionary is an abstract data type composed of a collection of (key, value) pairs, such that each possible key appears just once in the collection.
In java in particular as already mentioned this is easily done with a HashMap.
HashMap<Integer, Integer> cache = new HashMap<Integer, Integer>();
You can insert elements with the method put
cache.put(21, 42);
and you can retrieve a value with get
Integer key = 21
Integer value = cache.get(key);
System.out.println("Key: " + key +" value: "+ value);
Key: 21 value: 42
If you want to iterate through data you need to define an iterator:
Iterator<Integer> Iterator = cache.keySet().iterator();
while(Iterator.hasNext()){
Integer key = Iterator.next();
System.out.println("key: " + key + " value: " + cache.get(key));
}
Sounds like HashMap<Integer,Integer> is what you're looking for.
If you are willing to use an external library, you can use apache's IntToIntMap, which is a part of Apache Lucene.
It implements a pretty efficient int to int map that uses primitives for tasks that should not suffer the boxing overhead.
If you have a limit for the size of the first list, you can just use a large array. Suppose you know there first list only has numbers 0-99, you can use int[100]. Use the first number as an array index.
Your requirements can be satisfied by the Map interface. As an example, see HashMap<K,V>.
See Map and HashMap
I have the following key-value system (HashMap) , where String would be a key like this "2014/12/06".
LinkedHashMap<String, Value>
So, I can retrieve an item knowing the key, but what I'm looking for is a method to retrieve a list of the value which key matches partialy, I mean, how could I retrieve all the values of 2014?.
I would like to avoid solutions like, test every item in the list, brute-force, or similar.
thanks.
Apart from doing the brute-force solution of iterating over all the keys, I can think of two options :
Use a TreeMap, in which the keys are sorted, so you can find the first key that is >= "2014/01/01" (using map.getCeilingEntry("2014/01/01")) and go over all the keys from there.
Use a hierarchy of Maps - i.e. Map<String,Map<String,Value>>. The key in the outer Map would be the year. The key in the inner map would be the full date.
Not possible with LinkedHashMap only. If you can copy the keys to an ordered list you can perform a binary search on that and then do a LinkedHashMap.get(...) with the full key(s).
If you're only ever going to want to retrieve items using the first part of the key, then you want a TreeMap rather than a LinkedHashMap. A LinkedHashMap is sorted according to insertion order, which is no use for this, but a TreeMap is sorted according to natural ordering, or to a Comparator that you supply. This means that you can find the first entry that starts with 2014 efficiently (in log time), and then iterate through until you get to the first one that doesn't match.
If you want to be able to match on any part of the key, then you need a totally different solution, way beyond a simple Map. You'd need to look into full text searching and indexing. You could try something like Lucene.
You could refine a hash function for your values so that values with similar year would hash around similar prefixed hashes. That wouldn't be efficient (probably poor distribution of hashes) nor to the spirit of HashMaps. Use other map implementations such as TreeMaps that keep an order of your choice.
While debugging I found a strange behavior.
I got a HashMap<Integer, Set<Term>> (Term is a class which only contains a String) the normal toString() shows this:
When I click the table property of the HashMap I get this:
My Question now, why are there null values in the table toString() ?
Edit: Thanks for your fast answers! If I could, I would accept all of them...
HashMap is a Map implementation that's crucial feature is constant time O(1) lookup.
The only data structure in computer science with constant time lookup is an array of fixed length. When you initialise the HashMap it's creating a fixed length array that it will expand when your entries exceed the current array's size.
Edit: #kutschkem has pointed out that java.util.HashMap expands its fixed length array when the number of entries is around 80% of the current array's size, rather than when the entries exceed the current array's size.
Because the Map implementation you are using is working with a starting set of HashBuckets some of which are NULL at beginning (determined by initialCapacity). If you exceed the number of entries it will start creating more HashBuckets / slots for your Objects. Think of this as a growth reserve the HashMap automatically creates for you.
Read more:
https://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html
The HashMap stores its entries in a hashtable. That is an array, and the hash function maps the key to one of the array entries (also called hash buckets).
The hash buckets are always at least 20% empty. If they are not, then the array is resized to make sure there is enough free space.
The reason is that as the hash table gets filled up, collisions between hashes get more and more likely. You lose all advantages of the HashMap if collisions are too frequent. Too full, and your HashMap would be no better than a LinkedList (yes, LinkedList, not ArrayList). It would probably be even worse.
That is how a hash map work: a large array (table), and for some key the following table entry is tried:
table[key.hashCode() % table.length]
That table slot then is used. Rehashing is used if there already is a key that is not equals(key).
So initially the table contains only nulls, and has size initialCapacity. The array can be grown when the hash map becomes too filled (loadFactor).
The HashMap uses internally an array to store the entries. Very much simplified, it does something like array_index = hashcode % array_length (again: very simplified, as it also needs to take care of hash collisions etc). This internal array is typically larger than the number of elements you store in the HashMap -- otherwise, the array would have to be resized every time you add an element to it. So what you see as null are the yet unused slots in the array.
This is normal behavior.
There are null values because the table array was initialized as being filled with nulls, and uses null to indicate that there are no values stored in that hash bucket.
The toString() function provided doesn't skip over them because seeing them was useful to the folds debugging the HashMap implementation.
If you want to see the contents without the nulls, you'll have to write your own display function, either by subclassing HashMap and overriding toString() or by providing a convenience function somewhere in your code.