Regarding Java Map and Array [closed] - java

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
In Javascript, We can write statement as below.
var f_names = {
'a' : 'Apple',
'b' : 'Banana'
'c' : 'Carrot'
};
I can call this as f_names['c'] and get output as Carrot.
Is there any equivalent to this in Java instead of Map ? Similar to above ?
We can create an String array as bellow in java.
String[] names= { "Apple","Banana", "Carrot" };
Then can call as names[2] and this will return output as Carrot.
I'm looking for solution like this.

That is not at all conditional statement. It's Javascript object. In Java also there is Map.
Yes, you are just looking for Map in Java. Which stores key value pairs.
Map<String, String> map= new HashMap<String, String>();
map.put("a", "Apple");
map.put("b", "Banana");
And you can retrieve like
String a = map.get("a");// which results "Apple"
Update: If you are looking for other ways
Take a method which returns String. Add switch case inside method and
return the result value.
Take an array of array ex ({{k,v},{},{}}). Iterate to get the
required value.
Update after your latest comment :
(Both JS and Java are languages. if JS can achieve it as above(in simple way), why we use Map for that in Java.)
You are comparing two languages syntax, it's highly impossible to work with same syntax. If you still want to find the same way, the below would be the closest
HashMap<String, String > map = new HashMap<String, String>(){{
put("a", "Apple");
put("b", "Banana");
}};
Not sure about your acceptance of this cheat ;)

Syntax is a bit more complex in Java.
To get the closest equivalent, you can use a TreeMap, which will order its keys (default in this case is lexicographic order):
Map<String, String> names = new TreeMap<String, String>();
names.put("a", "Apple");
names.put("b", "Banana");
names.put("c", "Carrot");
System.out.println(names);
Output
{a=Apple, b=Banana, c=Carrot}
If you really don't want to use a Map, you can use a double-dimensional array.
For instance:
String[][] namesArray = new String[][]{{"a","Apple"},{"b","Banana"},{"c","Carrot"}};
System.out.println(Arrays.deepToString(namesArray));
Output
[[a, Apple], [b, Banana], [c, Carrot]]
Notes
Amongst the many advantages of using a Map is the fact that you can retrieve your values by key, which is probably something of interest given your context. For instance: names.get("A") will return "Apple.
With the array, you will need to retrieve your values by indices. For instance, namesArray[1][1] is "Banana".

Though Map is the thing you would really want, you could also use enums (I can't really help with those; I lack routine) and public static variables:
public final static String a = "Apple";
public final static String b = "Banana";
public final static String c = "Carrot";
Then they would be referencable from anywhere in the program. Say if the variables resided in a class named Fruits, they would be referenced to like this:
Fruits.a
Fruits.b
Fruits.c

This a Javascript Object(Java Script Object Notation) and it is more or less like a key-value pair. In Java this can be achieved by Map interface and the heavily used implementation of this interface is HashMap.

Related

Comparing key elements of a Map using their hash codes [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I want to compare the elements of a map using HashCode. Is it possible to do so?
For example, my HashMap looks like this:
HashMap<Integer,String> map=new HashMap<Integer, String>();
map.put(123,"ABC");
map.put(345,"Abc");
map.put(245,"abc");
I assume that all the values must have same hash codes, so that I can compare them and get all keys(123,345,245).
Is my assumption correct? Can I use hash codes in order to compare the keys?
It seems to me that what you really want is to make the name to be key of the map and the corresponding telephone number set the value.
Also you want that your keys are not case sensitive... String instances that differ in case will have different hash-codes and so you cannot use them here as the key per se. What you need to do then is to transform names into a canonical form, say all lowercase, when accessing the map so that difference in case is not relevant any longer.
There is a few way to go about this... extending a HashMap to suit your needs is an elegant one.
Better to use a String to store phone number as often they do contain non numeric characters...
public class PhoneBook extends HashMap<String,Set<String>> {
public PhoneBook() { }
public PhoneBook(int initialCapacity) { super(initialCapacity); }
// Use this method to add numbers to the phone-book
// returns true if the phone directory changed as a result of the call.
public boolean add(String name, String number) {
String canonicalName = name.toLowerCase();
Set<String> existingNumbers = super.get(name);
if (existingNumbers == null)
super.put(canonicalName,existingNumbers = new HashSet<>(10));
// give an estimate capacity per name, in this example 10.
return existingNumbers.add(number);
}
#Override
public Set<String> put(String name, Set<String> numberSet) {
throw new UnsupportedOperationException("you must use add(String) to add numbers");
}
#Override
public Set<String> get(String name) {
String canonicalName = name.toLowerCase();
Set<String> existingNumbers = super.get(canonicalName);
return existingNumbers == null ? Collections.EMPTY_SET : existingNumbers;
}
}
You may need to override some other operations from Map/Hash map to make sure consistency is preserved.
You don't need to do that explicitly.
HashMap already hashes its keys.
Just invoke: map.keySet() to get the Set of your keys.
Example
HashMap<Integer,String> map = new HashMap<Integer, String>();
map.put(123,"ABC");
map.put(345,"Abc");
map.put(245,"abc");
System.out.println(map.keySet());
Output
[245, 123, 345]
What if I need the keys sorted (here, in their natural order)?
Two solutions.
Use a TreeMap instead
Map<Integer,String> map = new TreeMap<Integer, String>();
Wrap the Set around a TreeSet later on
System.out.println(new TreeSet<Integer>(map.keySet()));
There are different ways to achieve this i.e. single key -> multi values
Using Hashmap and arraylist combine
Using guava collections's multimap
Using multimap provided by apache commons collection
Here is detail explanation:
http://java.dzone.com/articles/hashmap-%E2%80%93-single-key-and
Your assumption is not correct.
From Wikipedia:
In the Java programming language, every class implicitly or explicitly
provides a hashCode() method, which digests the data stored in an
instance of the class into a single hash value (a 32-bit signed
integer). This hash is used by other code when storing or
manipulating the instance (...). This property is important to the
performance of hash tables and other data structures that store
objects in groups ("buckets") based on their computed hash values.
Now, each of your instance has a hash code that can be same or different with the hash code of other objects. The Map collection uses that hash code (via the hashcode() method) of your keys in order to store data in buckets internally (If you want more details on this, look here).
As aforementioned, this does not mean that all the objects stored in the same bucket have for sure the same or different hash code though.
UPDATE: Why do you want to compare the objects using their hash codes? If you want to compare the keys or the values of the map, I suggest that you make a value or object comparison by iterating the set of them (you can get them by map.keySet() or map.values() respectively) and not by using hash code. You can not be sure whether or not the value from hashCode() will be the same or different for different objects.

How to declare and assign the values to a hashMap directly

Like String s="sample" in java.How to declare and assign values to a hashMap in one step. Also is it possible to assign more set of values at a time using put function in hashMap.
Yes, it is possible. you can use the below code
HashMap<String,String> instruments = new HashMap<String, String>() {
{
put("test","test");
put("test1","test1");
}
};
Use a library like Google Guava which has lots of utilities to instantiate HashMaps. It is also possible doing anonymous inheritance like this:
Map<String, Object> map = new HashMap<String, Object>() {{
put("Test", "Test1");
put("Test", "Test1");
}};
But I wouldn't recommend it.
such constructs do not exist in good ol' java.
On one hand, you can use property files format for that. You can save your map as a something-separated key-value pairs in a string or a file, and read them in a loop filling your map with each pair.
on the other hand, if you really need that + possible type-checking, you can look at modern dynamic JVM languages, like Groovy or Scala.
there you can use the code as it is:
def map = [ a:1, b:23, c:"aasdasd" ]

Comparing TreeMap contents gives incorrect answer

I use a TreeMap as a 'key' inside another TreeMap
ie
TreeMap<TreeMap<String, String>, Object>
In my code 'object' is a personal construct, but for this intance I have used a string.
I have created a pair of TreeMaps to test the TreeMap.CompareTo() and TreeMap.HashCode() methods. this starts with the following...
public class TreeMapTest
public void testTreeMap()
{
TreeMap<String, String> first = new TreeMap<String, String>();
TreeMap<String, String> second = new TreeMap<String, String>();
first.put("one", "une");
first.put("two", "deux");
first.put("three", "trois");
second.put("une", "one");
second.put("deux", "two");
second.put("trois", "three");
TreeMap<TreeMap<String, String>, String> english = new TreeMap<TreeMap<String, String>, String>();
TreeMap<TreeMap<String, String>, String> french = new TreeMap<TreeMap<String, String>, String>();
english.put(first, "english");
french.put(second, "french");
From here I now call the the english item to see if it contains the key
if (english.containsKey(second))
{
System.out.println("english contains the key");
//throws error of ClassCastException: Java.util.TreeMap cannot be cast to
//Java.Lang.Comparable, reading the docs suggests this is the feature if the key is
//not of a supported type.
//this error does not occur if I use a HashMap structure for all maps, why is
//this key type supported for one map structure but not another?
}
However I should note that both HashMap and TreeMap point to the same HashCode() method in the AbstractMap parent.
My first thought was to convert my TreeMap to a HashMap, but this seemed a bit soppy! So I decided to apply the hashCode() method to the 2 treemap objects.
int hc1 = first.hashCode();
int hc2 = second.hashCode();
if(hc1 == hc2)
{
systom.out.printline("values are equal " + hc1 + " " + hc2);
}
prints the following
values are equal 3877431 & 3877431
For me the hashcode should be different as the key values are different, I can't find details on the implementation difference of the hashCode() method between HashMap and TreeMap.
Please not the following.
changing the Keys only to HashMap doesn't stop the ClassCastException error. Changing all the maps to a HashMap does. so there is something with the containsKey() method in TreeMap that isn't working properly, or I have missunderstood - can anyone explain what?
The section where I get the hashCode of the first and second map objects always produces the same output (no matter if I use a Hash or Tree map here) However the if(english.ContainsKey(second)) doesn't print any message when HashMaps are used, so there is obviously something in the HashMap implementation that is different for the compareTo() method.
My principle questions are.
Where can I find details of the types of keys for use in TreeMap objects (to prevent future 'ClassCastException' errors).
If I can't use a certain type of object as a key, why am I allowed to insert it as a key into the TreeMap in the first place? (surely if I can insert it I should be able to check if the key exists?)
Can anyone suggest another construct that has ordered inster / retrieval to replace my TreeMap key objects?
Or have I potentially found strange behaviour. From my understanding I should be able to do a drop in replacement of TreeMap for HashMap, or have I stumbled upon a fringe scenario?
Thanks in advance for your comments.
David.
ps. the problem isn't a problem in my code as I use a personal utility to create a hash that becomes dependent on the Key and Value pairs (ie I calculate key hash values differently to value hash values... sorry that if is a confusing sentence!) I assume that the hashCode method just sums all the values together without considering if a item is a key or a value.
pps. I'm not sure if this is a good question or not, any pointers on how to improve it?
Edit.
from the responses people seem to think I'm doing some sort of fancy language dictionary stuff, not a surprise from my example, so sorry for that. I used this as an example as it came easily to my brain, was quick to write and demonstrated my question.
The real problem is as follows.
I'm accessing a legacy DB structure, and it doesn't talk nicely to anything (result sets aren't forward and reverse readable etc). So I grab the data and create objects from them.
The smallest object represents a single row in a table (this is the object that in the above example I have used a string value 'english' or 'french' for.
I have a collection of these rowObjects, each row has an obvious key (this is the TreeMap that points to the related rowObject).
i don't know if that makes things any clearer!
Edit 2.
I feel I need to elaborate a little further as to my choice of originaly using
hashMap<HashMap<String,string>, dataObject>
for my data structure, then converting to TreeMap to gain an ordered view.
In edit 1 I said that the legacy DB doesn't play nicely (this is an issue with the JDBC.ODBC I suspect, and I'm not about to acquire a JDBC to communicate with the DB). The truth is I apply some modifications to the data as as I create my java 'dataObject'. This means that although the DB may spit out the results in ascending or descending order, I have no way of knowing what order they are inserted into my dataObject. Using a likedHashMap seems like a nice solution (see duffymo's suggestion) but I later need to extract the data in an ordered fashion, not just consecutively (LinkedHashMap only preserves insertion order), and I'm not inclined to mess around with ordering everything and making copies when I need to insert a new item in between 2 others, TreMap would do this for me... but if I create a specific object for the key it will simply contain a TreeMap as a member, and obviously I will then need to supply a compareTo and hashCode method. So why not just extent TreeMap (allthough Duffymo has a point about throwing that solution out)!
This is not a good idea. Map keys must be immutable to work properly, and yours are not.
What are you really trying to do? When I see people doing things like this with data structures, it makes me think that they really need an object but have forgotten that Java's an object-oriented language.
Looks like you want a crude dictionary to translate between languages. I'd create a LanguageLookup class that embedded those Maps and provide some methods to make it easier for users to interact with it. Better abstraction and encapsulation, more information hiding. Those should be your design objectives. Think about how to add other languages besides English and French so you can use it in other contexts.
public class LanguageLookup {
private Map<String, String> dictionary;
public LanguageLookup(Map<String, String> words) {
this.dictionary = ((words == null) ? new HashMap<String, String>() : new HashMap<String, String>(words));
}
public String lookup(String from) {
return this.dictionary.get(from);
}
public boolean hasWord(String word) {
return this.dictionary.containsKey(word);
}
}
In your case, it looks like you want to translate an English word to French and then see if the French dictionary contains that word:
Map<String, String> englishToFrenchWords = new HashMap<String, String>();
englishToFrenchWords.put("one", "une");
Map<String, String> frenchToEnglishWords = new HashMap<String, String>();
frenchToEnglishWords.put("une", "one");
LanguageLookup englishToFrench = new LanguageLookup(englishToFrenchWords);
LanguageLookup frenchToEnglish = new LanguageLookup(frenchToEnglishWords);
String french = englishToFrench.lookup("one");
boolean hasUne = frenchToEnglish.hasWord(french);
Your TreeMap is not Comparable so you can't add it to a SortedMap and its not immutable so you can't add it to a HashMap. What you could use an IdentityMap but suspect an EnumMap is a better choice.
enum Language { ENGLISH, FRENCH }
Map<Language, Map<Language, Map<String, String>>> dictionaries =
new EnumMap<>(Language.class);
Map<Language, Map<String, String>> fromEnglishMap = new EnumMap<>(Language.class);
dictionaries.put(Language.ENGLISH, fromEnglishMap);
fromEnglishMap.put(Language.FRENCH, first);
Map<Language, Map<String, String>> fromFrenchMap = new EnumMap<>(Language.class);
dictionaries.put(Language.FRENCH, fromFrenchMap);
fromEnglishMap.put(Language.ENGLISH, second);
Map<String, String> fromEnglishToFrench= dictionaries.get(Language.ENGLISH)
.get(Language.FRENCH);
To the problem why Hashmap works and Treemap does not:
A Treemap is a "sorted map", meaning that the entries are sorted according to the key. This means that the key must be comparable, by implementing the Comparable interface. Maps usually do NOT implement this, and I would highly suggest you do not create a custom type to add this feature. As duffymo mentions, using maps as keys is a BAD idea.

Does Java support associative arrays? [duplicate]

This question already has answers here:
Java associative-array
(15 answers)
Closed 6 years ago.
I'm wondering if arrays in Java could do something like this:
int[] a = new int[10];
a["index0"] = 100;
a["index1"] = 100;
I know I've seen similar features in other languages, but I'm not really familiar with any specifics... Just that there are ways to associate values with string constants rather than mere numeric indexes. Is there a way to achieve such a thing in Java?
You can't do this with a Java array. It sounds like you want to use a java.util.Map.
Map<String, Integer> a = new HashMap<String, Integer>();
// put values into the map
a.put("index0", 100); // autoboxed from int -> Integer
a.put("index1", Integer.valueOf(200));
// retrieve values from the map
int index0 = a.get("index0"); // 100
int index1 = a.get("index1"); // 200
I don't know a thing about C++, but you are probably looking for a Class implementing the Map interface.
What you need is java.util.Map<Key, Value> interface and its implementations (e.g. HashMap) with String as key
To store things with string keys, you need a Map. You can't use square brackets on a Map. You can do this in C++ because it supports operator overloading, but Java doesn't.
There is a proposal to add this syntax for maps, but it will be added for Java 8 at the earliest.
Are you looking for the HashMap<k,v>() class? See the javadocs here.
Roughly speaking, usage would be:
HashMap<String, int> a = new HashMap<String,int>();
a.put("index0", 100);
etc.
java does not have associative arrays yet. But instead you can use a hash map as an alternative.

Creating Variables at Runtime in Java [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
In my code I have a pretty big loop and I need to create a new variable at the end of each iteration (integers). Is this possible? I read about a ScriptEngineManager class, but I'm not sure if this will be able to help. I suppose I could create a bunch of integers equal to 0, but I'm not exactly sure how many times I will need to create a new variable (it depends on the conditions of the loop). Hopefully this makes sense.
Use an array. In Javascript, place var results = [] before your loop and append results using results.push(value). In Java, you'll want to use an ArrayList. (Those are very different languages, by the way.)
Hopefully this makes sense.
Unfortunately, it doesn't.
In Java it makes no sense to create variables on the fly. It is extremely difficult to do, and once you have done it they are extremely difficult to use. (By contrast, it is easy to do in Javascript ...)
However, this just means that you need to do what you are trying to in a different way. For instance, the following does a computation in a loop and then saves the results in an (existing) ArrayList variable:
List<Integer> results = ArrayList<Integer>();
while (...) {
// Do computation ...
int result = ...
results.add(result);
}
// Now we have all of the results in 'results'
Or, if you want to bind each of the results to a distinct name, you could do something like this:
Map<String, Integer> results = HashMap<String, Integer>();
while (...) {
// Do computation ...
String name = ...
int result = ...
results.put(name, result);
}
Following is the way that i have implemented and helped me to fix my solution easily without much hurdles.
// Creating the array List
List accountList = new ArrayList();
for(int k=0;k < counter;k++){
accountList.add(k, (String)flowCtx.getValueAt("transitId"+m));
}
Iterating the loop and adding the objects into the arraylist with the index.
//Retrieving the object at run time with the help of the index
String a = accountList.get(i));
No, It is not possible to declare variables in java at runtime. But java provides java.util.map, which can be used like in the example below. We can assume that the key is the variable name.
Map<String, Object> declareVariableRuntime= new HashMap<String, Object>(); declareVariableRuntime.put("variableName", new Object());

Categories

Resources