what is the difference between these two object initialization in java? - java

If i use:
HashMap<String, Integer> test = new HashMap<String, Integer>();
Or i use:
HashMap test = new HashMap();
Is there any difference on further methods that i can apply on test object. like test.put(), test.get() etc if initialized differently??
Also if i put something in test object e.g like:
test.put("One", new Integer(5));
test.put("Two", new Integer(4));
test.put("Three", new Integer(3));
and display it as:
Set set = tokens.entrySet();
Iterator ik = test.iterator();
while(ik.hasNext()){
Map.Entry me = (Map.Entry)ik.next();
System.out.println(me.getKey() + " : " + me.getValue() );
The result is not sorted, restul is:
Three: 3
One: 5
Two: 1
What rule it does follow?? Is this normal behavior for the output to be randomly displayed??

In the first case Hashmap keys must be Strings and values must be Integers. The compiler will perform the respective type checking. In the second case any kind of objects can be used.
This is completely normal that your HashMap entries are printed in random order. If you want to preserve the order use LinkedHashMap instead.

In first example you can only put Strings as keys and Integers as values, but in second example you can put anything to the map and the compiler can't help you to get type safety.
Read more about how Java Generics works.

Yes, you'll get "random" iteration order when using HashMap. If you need a Map implementation with predictable iteration order, check out LinkedHashMap.

In the first case, key must be String and value must be Integer.
In the second case, key and value can be object of anytype.
HashMap and HashSet does not guarantee the insertion order. If you want it to remain in the order at which you insert the value, try LinkedHashMap. Much clearer was answered in previous StackOverflow question here

I think that depends on your usage ,
if you need a compiler to allow you to add only String as Key and Integer as value , then you need to specify both parameters type,
otherwise if you need to pass anything without any restriction then use the second one.

Related

How to convert two arrays into one map<k,v>

I have two Arrays,
String[] stageIdList =[V0S186,V0S191,V75S0,V76S0,V0S200,V78S0,V130A0,V0A203];
String[] stageNameList = [Src_DRI_JFP_MISLOG_sf,Tfm_DRI_JFP_MISLOG,Tgt_DRI_JFP_MISLOG,Tgt_A_JFP_MISLOG_D_DS,Sequential_File_200,Sequential_File_201, ,\(20)];
They are in keys: values combination. How do I find equivalent value for a particular key when called?
Will Hashmap be useful in this case? If yes, how do I make for two lists?
PS. I am new to java
I think you want to get some value from StageIdList by value in StageNameList.
You may create
Map<String,String> map = new HashMap<>
for(int i=0;i<stageNameList.size){
map.put(name,stageIdList.get(i));
}
And get value by key:
map.get(key);
key - your name from stageNameList
Would you mind telling more about the question?
1) If you want to do something like:
Give you a stageID, you should return the stageName.
Then you only need one hashmap, where the stageID is the key and the stageName is the value. The solution is similar to Артем К's answer. Though there should be a ++i in the for loop and stageNameList.length and stageIDList[i] as the stageNameList is actually an array.
2) However, if you want to do a two-direction mapping like this:
Give you a stageID, you should return the stageName. AND if give you a stageName, you should return the stageID.
You may need to create two hashmaps. Or you need to do a entrySet to iterate, etc.

Is there an efficient way of checking if HashMap contains keys that map to the same value?

I basically need to know if my HashMap has different keys that map to the same value. I was wondering if there is a way other than checking each keys value against all other values in the map.
Update:
Just some more information that will hopefully clarify what I'm trying to accomplish. Consider a String "azza". Say that I'm iterating over this String and storing each character as a key, and it's corresponding value is some other String. Let's say I eventually get to the last occurrence of 'a' and the value is already be in the map.This would be fine if the key corresponding with the value that is already in the map is also 'a'. My issue occurs when 'a' and 'z' both map to the same value. Only if different keys map to the same value.
Sure, the fastest to both code and execute is:
boolean hasDupeValues = new HashSet<>(map.values()).size() != map.size();
which executes in O(n) time.
Sets don't allow duplicates, so the set will be smaller than the values list if there are dupes.
Very similar to EJP's and Bohemian's answer above but with streams:
boolean hasDupeValues = map.values().stream().distinct().count() != map.size();
You could create a HashMap that maps values to lists of keys. This would take more space and require (slightly) more complex code, but with the benefit of greatly higher efficiency (amortized O(1) vs. O(n) for the method of just looping all values).
For example, say you currently have HashMap<Key, Value> map1, and you want to know which keys have the same value. You create another map, HashMap<Value, List<Key>> map2.
Then you just modify map1 and map2 together.
map1.put(key, value);
if(!map2.containsKey(value)) {
map2.put(value, new ArrayList<Key>);
}
map2.get(value).add(key);
Then to get all keys that map to value, you just do map2.get(value).
If you need to put/remove in many different places, to make sure that you don't forget to use map2 you could create your own data structure (i.e. a separate class) that contains 2 maps and implement put/remove/get/etc. for that.
Edit: I may have misunderstood the question. If you don't need an actual list of keys, just a simple "yes/no" answer to "does the map already contain this value?", and you want something better than O(n), you could keep a separate HashMap<Value, Integer> that simply counts up how many times the value occurs in the map. This would take considerably less space than a map of lists.
You can check whether a map contains a value already by calling map.values().contains(value). This is not as efficient as looking up a key in the map, but still, it's O(n), and you don't need to create a new set just in order to count its elements.
However, what you seem to need is a BiMap. There is no such thing in the Java standard library, but you can build one relatively easily by using two HashMaps: one which maps keys to values and one which maps values to keys. Every time you map a key to a value, you can then check in amortized O(1) whether the value already is mapped to, and if it isn't, map the key to the value in the one map and the value to the key in the other.
If it is an option to create a new dependency for your project, some third-party libraries contain ready-made bimaps, such as Guava (BiMap) and Apache Commons (BidiMap).
You could iterate over the keys and save the current value in the Set.
But, before inserting that value in a Set, check if the Set already contains that value.
If this is true, it means that a previous key already contains the same value.
Map<Integer, String> map = new HashMap<>();
Set<String> values = new HashSet<>();
Set<Integter> keysWithSameValue = new HashSet<>();
for(Integer key : map.keySet()) {
if(values.contains(map.get(key))) {
keysWithSameValue.add(key);
}
values.add(map.get(key));
}

How to check if a key in a Map starts with a given String value

I'm looking for a method like:
myMap.containsKeyStartingWith("abc"); // returns true if there's a key starting with "abc" e.g. "abcd"
or
MapUtils.containsKeyStartingWith(myMap, "abc"); // same
I wondered if anyone knew of a simple way to do this
Thanks
This can be done with a standard SortedMap:
Map<String,V> tailMap = myMap.tailMap(prefix);
boolean result = (!tailMap.isEmpty() && tailMap.firstKey().startsWith(prefix));
Unsorted maps (e.g. HashMap) don't intrinsically support prefix lookups, so for those you'll have to iterate over all keys.
From the map, you can get a Set of Keys, and in case they are String, you can iterate over the elements of the Set and check for startsWith("abc")
To build on Adel Boutros answer/comment about the efficiency of iterating keys, you could encapsulate key iteration in a Map subclass or decorator.
Extending HashMap would give you a class to put the method in and keep map-specific code out of your method, so lowering complexity and making the code more natural to read.

Java Map question

I have one Map that contains some names and numbers
Map<String,Integer> abc = new HashMap<String,Integer>();
It works fine. I can put some values in it but when I call it in different class it gives me wrong order. For example:
I putted
abc.put("a",1);
abc.put("b",5);
abc.put("c",3);
Iterator<String> iter = abc.keySet().iterator();
while (iter.hasNext()) {
String name = iter.next();
System.out.println(name);
}
some time it returns the order (b,a,c) and some time (a,c,b).
What is wrong with it? Is there any step that I am missing when I call this map?
Edit:
I changed to HashMap and result is still same
The only thing that's wrong is your expectations. The Map interface makes no guarantees about iteration order, and the HashMap implementation is based on hash functions which means the iteration order is basically random, and will sometimes change completely when new elements are added.
If you want a specific iteration order, you have thee options:
The SortedMap interfaces with its TreeMap implementation - these guarantee an iteration order according to the natural ordering of the keys (or an ordering imposed by a Comparator instance)
The LinkedHashMap class iterates in the order the elements were added to the map.
Use a List instead of a Map - this has a well-defined iteration order that you can influence in detail.
I think you need LinkedHashMap.
A TreeMap will always have keys in their natural order (unless you provide a comparator) If you are seeing the order any differently it will be the way you are looking at the map and what you are doing with it. If in doubt, use a debugger and you will see the order is sorted.
If you wish to get map values in the same order you used to insert them use LinkedHashMap instead.

Java queue and multi-dimension array

First of all, this is my code (just started learning java):
Queue<String> qe = new LinkedList<String>();
qe.add("b");
qe.add("a");
qe.add("c");
qe.add("d");
qe.add("e");
My question:
Is it possible to add element to the queue with two values, like:
qe.add("a","1"); // where 1 is integer
So, that I know element "a" have value 1. If I want to add a number let say "2" to element a, I will have like a => 3.
If this cant be done, what else in java classes that can handle this? I tried to use multi-dimention array, but its kinda hard to do the queue, like pop, push etc. (Maybe I am wrong)
How to call specific element in the queue? Like, call element a, to check its value.
[Note]
Please don't give me links that ask me to read java docs. I was reading, and I still dont get it. The reason why I ask here is because, I know I can find the answer faster and easier.
You'd want to combine a Queue<K> with a Map<K,V>:
Put the keys (e.g. "a", "b") into the Queue<K>
Assign the mapping of the keys to values (e.g. "a"=>3) in the Map<K,V>
I think you're asking for a dictionary type in Java.
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("a", 1);
map.put("b", 2);
You can then access them by key - in this case the String you choose as the key.
int value = map.get("a");
Value in this case will return 1.
Is that what you want?
You want to use a HashMap instead of LinkedList. HashMap is a dictionary-like structure that allows you to create associations, for instance a=>1.
Check out JavaDocs for HashMap to get a grasp how to use it:-).
I think what you are asking for is LinkedHashMap which is a combination of a Queue and a HashMap. While you are able to store the key and value pairs, it would also remember the order like Queue does. The only thing is you'd have to use an iterator since there is no poll() method, however you can visit each element in the order that they were added.

Categories

Resources