I am trying to code a Graph in java and one of my member variables is a map that maps strings to integers. The integers are the indexes of a List<List<Integer>>. Lets say I have a graph like
"Alpha" maps to 0,
"Beta" maps to 1,
"Charlie" maps to 2,
"Delta" maps to 3.
If I delete Beta from my graph, I want to shift Charlie and Delta down. But, the Java map function can only get the values not the keys, so I can't change the mappings. How should I go about doing this?
Use LinkedHashMap. There the insertion order of the keys are maintained.
If you want to maintain keys in an alphabetical order (or any other way), then use TreeMap. In this case, once you delete an entry, keys will sort themselves according to the rule (e.g. alphabetical order). The beauty of TreeMap is you can define the sorting rule here.
But, in any case HashMap is not a proper choice for you.
Hashmap is the best to link between two deferent objects see this example
Related
I'm completely new to programming and to java in particular and I am trying to determine which data structure to use for a specific situation. Since I'm not familiar with Data Structures in general, I have no idea what structure does what and what the limitations are with each.
So I have a CSV file with a bunch of items on it, lets say Characters and matching Numbers. So my list looks like this:
A,1,B,2,B,3,C,4,D,5,E,6,E,7,E,8,E,9,F,10......etc.
I need to be able to read this in, and then:
1)display just the letters or just the numbers sorted alphabetically or numerically
2)search to see if an element is contained in either list.
3)search to see if an element pair (for example A - 1 or B-10) is contained in the matching list.
Think of it as an excel spreadsheet with two columns. I need to be able to sort by either column while maintaining the relationship and I need to be able to do an IF column A = some variable AND the corresponding column B contains some other variable, then do such and such.
I need to also be able to insert a pair into the original list at any location. So insert A into list 1 and insert 10 into list 2 but make sure they retain the relationship A-10.
I hope this makes sense and thank you for any help! I am working on purchasing a Data Structures in Java book to work through and trying to sign up for the class at our local college but its only offered every spring...
You could use two sorted Maps such as TreeMap.
One would map Characters to numbers (Map<Character,Number> or something similar). The other would perform the reverse mapping (Map<Number, Character>)
Let's look at your requirements:
1)display just the letters or just the numbers sorted alphabetically
or numerically
Just iterate over one of the maps. The iteration will be ordered.
2)search to see if an element is contained in either list.
Just check the corresponding map. Looking for a number? Check the Map whose keys are numbers.
3)search to see if an element pair (for example A - 1 or B-10) is
contained in the matching list.
Just get() the value for A from the Character map, and check whether that value is 10. If so, then A-10 exists. If there's no value, or the value is not 10, then A-10 doesn't exist.
When adding or removing elements you'd need to take care to modify both maps to keep them in sync.
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.
When I was going through a example code which has ListViews I came up with LinkedHashMap.
What is a LinkedHashMap and where can we use it and how? I went through several articles but did not understand fully. Is it necessary when creating ListView. What is the connection between ListViews and LinkedHashMaps? Thank you.
For Simplicity, let us understand what is the difference between HashMap and LinkedHashMap.
HashMap: It gives output in Random orders means there is no proper sequence how we have inserted values.
whereas
LinkedHashMap: It gives output in sequential order.
Let us see a small example: with HashMap
// suppose we have written a program
.
.
// now use HashMap
HashMap map = new HashMap(); // create object
map.put(1,"Rohit"); // insert values
map.put(2,"Rahul");
map.put(3,"Ajay");
System.out.println("MAP=" +map); //print the output using concatenation
//So the output may be in any order like we can say the output may be as:
Map={3=Ajay,2=Rahul,1=Rohit}
but this is not the case in LinkedHashMap
Just replace the "HashMap" with "LinkedHashMap" in the above code
and see
it will display the output in Sequential order like 1=Rohit will be displayed first then the others in sequence.
The docs are here. But its basically a HashMap that also has a linked list, so you can have a consistently ordered iteration through it. Note that this means removals may be O(n) time because you need to remove it from both data structures.
LinkedHashMap is hashmap. But it maintains order of insertion. But HashMap doesnt maintain order.
Hi Linked Hash Map is a Map which stored key value pair,
Linked Hash Map add the values may very slow, But while retrieving the values is very easy.
For fast retrieval of values we could prefer Linked Hash Map.
I have this very simple piece of code, and I was just trying to play a bit with different kind of objects inside a Map.
//There's a bit of spanish, sorry about that
//just think 'persona1' as an object with
//a string and an int
Map mapa = new HashMap();
mapa.put('c', 12850);
mapa.put(38.6, 386540);
mapa.put("Andrés", 238761);
mapa.put(14, "Valor de 14");
mapa.put("p1", persona1);
mapa.put("Andrea", 34500);
System.out.println(mapa.toString());
And then I expect from console something like:
{c=12850, 38.6=386540, Andrés=238761, 14=Valor de 14, p1={nombre: Andres Perea, edad: 10}, Andrea=34500}
But susprisingly for me I got same data in different order:
{38.6=386540, Andrés=238761, c=12850, p1={nombre: Andres Perea, edad: 10}, Andrea=34500, 14=Valor de 14}
It doesn't matter if I try other kind of objects, even just Strings or numeric types, it always does the same, it makes a different without-apparently-any-sense order.
Can someone give me a hint why this happens? Or may be something too obvious I'm missing?
I'm using Java 1.7 and Eclipse Juno.
As per Oracle's documentation
The HashMap class is roughly equivalent to Hashtable, except that it is unsynchronized and permits nulls. This class makes no guarantees as to the order of the map; in particular, it does not guarantee that the order will remain constant over time.
Refer to HashMap JavaDocs.
There are 3 class which implements map interface in java.
1. hashMap: Id does not guarantee any order.
2. Linked HashMap:It will store them in insertion order.
3. TreeMap: It will store in ascending order.(ASCII value)
So As per your requirement you can use Linked HashMap instead of HashMap.so instead of writing
Map mapa = new HashMap();
create object of Linked HashMap
Map mapa = new LinkedHashMap();
follow below link for more info.
http://docs.oracle.com/javase/tutorial/collections/interfaces/map.html
HashMap not guaranteed the order of element. If you want to keep order use LinkedHashMap.
See following case
Map<Integer,String> unOrderedMap=new HashMap<>();
unOrderedMap.put(1,"a");
unOrderedMap.put(3,"a");
unOrderedMap.put(2,"a");
System.out.println("HashMap output: "+unOrderedMap.toString());
Map<Integer,String> orderedMap=new LinkedHashMap<>();
orderedMap.put(1,"a");
orderedMap.put(3,"a");
orderedMap.put(2,"a");
System.out.println("LinkedHashMap output: "+orderedMap.toString());
Output:
HashMap output: {1=a, 2=a, 3=a}
LinkedHashMap output: {1=a, 3=a, 2=a}
Maps does not maintain the order the order in which elements were added, List will maintain the order of elements
"The order of a map is defined as the order in which the iterators on the map's collection views return their elements. Some map implementations, like the TreeMap class, make specific guarantees as to their order; others, like the HashMap class, do not."
This is how a hashmap works: (citing from another source)
It has a number of "buckets" which it uses to store key-value pairs in. Each bucket has a unique number - that's what identifies the bucket. When you put a key-value pair into the map, the hashmap will look at the hash code of the key, and store the pair in the bucket of which the identifier is the hash code of the key. For example: The hash code of the key is 235 -> the pair is stored in bucket number 235. (Note that one bucket can store more then one key-value pair).
When you lookup a value in the hashmap, by giving it a key, it will first look at the hash code of the key that you gave. The hashmap will then look into the corresponding bucket, and then it will compare the key that you gave with the keys of all pairs in the bucket, by comparing them with equals().
Now you can see how this is very efficient for looking up key-value pairs in a map: by the hash code of the key the hashmap immediately knows in which bucket to look, so that it only has to test against what's in that bucket.
Looking at the above mechanism, you can also see what requirements are necessary on the hashCode() and equals() methods of keys:
If two keys are the same (equals() returns true when you compare them), their hashCode() method must return the same number. If keys violate this, then keys that are equal might be stored in different buckets, and the hashmap would not be able to find key-value pairs (because it's going to look in the same bucket).
If two keys are different, then it doesn't matter if their hash codes are the same or not. They will be stored in the same bucket if their hash codes are the same, and in this case, the hashmap will use equals() to tell them apart.
Now, when you put all your "key-value" pairs in the hashmap, and print them, it prints them in some random order of the keys which got generated by hashing the value you supplied for keys.
If your requirement is still to maintain the ordering, you can use the LinkedHashMap in Java.
Hope this helps :-)
Edit: Original Post: How does a Java HashMap handle different objects with the same hash code?
So I have encountered the situation where I have a k/v map of destination to quantity, i.e. {San Francisco -> 10}, and I want to retrieve the k/v pair with the highest or lowest value, and then after retrieving it, I want to modify the value. TreeMap obviously has this functionality, but for the keys, not the values. Are there any packages or other ways to achieve this functionality? Thanks.
You can use BiMap from google guava.
Key/value maps are inherently unordered in most implementations (because they are implemented using hash tables). You'd need to iterate over all the values to determine the maximum. You should consider using a tuple with both the key and value, and then insert the tuple in a data structure that supports ordering.