I cannot seem to figure out how to access the values of my hashmap
What I am basically trying to do is create a hashmap with an array as one of the values like json style.. If that makes sense?
So I want something like hash{key: value1, value2, value3, [number1,number2]}
and be able to access it like (pseudocode:) hash.get(3).get(1)
public class WebSearch {
readFile.ReadFile xfile = new readFile.ReadFile("inputgraph.txt");
HashMap webSearchHash = new HashMap();
ArrayList belongsTo = new ArrayList();
ArrayList keyphrase = new ArrayList();
public WebSearch() {
}
public void createGraph()
{
HashMap <Object, ArrayList<Integer> > outlinks = new HashMap <Object, ArrayList<Integer>>();
for (int i = 0; i < xfile.getNumberOfWebpages(); i++ )
{
keyphrase.add(i,xfile.getKeyPhrases(i));
outlinks.put(keyphrase.get(i), xfile.getOutLinks(i));
}
}
keyphrases is an ArrayList
this is my output of System.out.print(outlinks);
{[education, news, internet]=[0, 3], [power, news]=[1, 4], [computer, internet, device, ipod]=[2], [university, education]=[5]}
How would I go about getting say just this: [education, news, internet]=[0, 3]
I have tried:
outlinks.get(xfile.getKeyPhrases(i))
xfile.getKeyPhrases(0) would for example return [education, news, internet]
You can get the key set (Map.keySet()) of the map first; outlinks.keySet()
Then you can use these keys on your map to get your entries (values of the keys)
You haven't posted enough of the surrounding code for your question to be entirely clear, but look at the Javadocs for Map. You will probably get what you want by iterating over outlinks.values().
I recommend to use a customized object and use it inside your collections.
You may create a POJO/Bean class and overwrite the toString method with the details that you want, for instance the a iterate over items inside a array.
When you use it to print or display the toString method will be call.
The following link show you some ideas:
http://www.javapractices.com/topic/TopicAction.do?Id=55
http://en.wikipedia.org/wiki/Plain_Old_Java_Object
You can access the keys of any HashMap using Map.keySet() method.
Also note that java.util.HashMap is unordered. HashMap makes no guarantees as to the order of the map; in particular, it does not guarantee that the order will remain constant over time.
You would like to relook at the structure of your HashMap, you are having ArrayList as your key.
Related
I am new in java arraylist. I have difficulties in creating arraylist. This is the example below. s1,s2,s3,s4,s5 is the category for people to choose and add number into it,
{[s1,0]}
{[s2,0]}
{[s3,0]}
{[s4,0]}
{[s5,0]}
For example, s1:2, s2:3, s1:3, s5:4, s3:2. How can i make the output to become like this
{[s1,5]}
{[s2,3]}
{[s3,2]}
{[s4,0]}
{[s5,4]}
I hope that someone can help me in this.
What you need here is a map. For example Map<String, Integer> map = new HashMap<String, Integer>();. Then to add you would do the following map.put("s1", 1);. An ArrayList is just an implementation of a list backed by an array and as such cannot have a key value pair. In order to update a value you would just do this:
int current = map.get("s1");
map.put("s1", current++);
If you need to track many values by a key then you would instead have a map of ArrayList, declared like so:
Map<String, ArrayList<Integer>> map = new HashMap<String,ArrayList<Integer>>();
ArrayList<Integer> s1sValues = new ArrayList<Integer>();
s1s.add(1);
s1s.add(2);
map.put("s1", s1sValues);
//To add to existing
map.get("s1").add(3);//If you don't already have a reference
s1sValues.add(4);//If you do have the reference.
`
Lets say I have hashmap store and it contains for example-(11,name1) (11,name2) and i call HashMap.get(11), it only shows name2 which means it overrides the first input for 11. How can i store both name1 and name2 with ID 11 using hashmap?I know i can use both HashMap and HashSet but i dont want to create every HashSet for HashMap. I just want to use hashSet only. how should I do this? I hope you can help me with it. Thank you.
public void insert(int ID, String key){
int hashKey = Hash(key);
System.out.println("Hash Key" + hashKey);
int node = Find(ID,hashKey);
storeR.put(node, key);
}
You can use:
HashMap<Integer, List<String>>
In HashMap you must put a value with every key. So of course, if you put the same key twice, the value will be override.
The solution is to hold a collection of values for every key.
in your code instead of:
storeR.put(node, key);
you should write:
List<String> nodeValues = storeR.get(node);
if (nodeValues == null) {
nodeValues = new ArrayList<String>();
storeR.put(node, nodeValues );
}
nodeValues.add(key);
And you should also change storeR type to be HashMap<Integer, List<String>>
MultiMap is also a similar solution.
You can probably use MultiMap from Apache Commons Collections.
You will have to either have a HashMap where the value of each key is another collection (list or set) or concatenate the string values together (e.g. comma separated).
Alternatively you may be able to find a data collection that supports multiple values per key.
To store multiple values for a single key, use a HashMap that contains a list as a value. HashMap's implementation overrides values for existing keys.
HashMap<Integer,List<String>>
Also, you could use MultiMap from Apache Commons or, if you're just using Integer I can suggest you use an array directly:
List<String>[] yourList = new List<String>[initCapacity];
So you can access that list like this:
yourList[0].add("A New Value");
As a final note, you can use any collection you deem appropiate, even a HashSet if performance is important for you and you won't store duplicated values for a same index.
I am creating Dictionary and an ArrayList such as this.
Dictionary testDict, testDict2 = null;
ArrayList al = new ArrayList();
testDict.put ("key1", dataVar1);
testDict.put ("key2", dataVar2);
testDict2.put ("key1", dataVar1);
testDict2.put ("key2", dataVar2);
al.add(testDict);
al.add(testDict2);
now my issue here is, how can I access the data within the dictionaries? Like for example how would I retrieve key1 from testDict using al?
Many thanks in advance :)
As you can read in the Java Docs all Dictionary objects (note that e.g. Hashtable is one of them) have a method Object get(Object key) to access it's elements. In your example you could access the value of the entry key1 in textDict like that:
// first access testDict at index 0 in the ArrayList al
// and then it's element with key "key1"
al.get(0).get("key1");
Note, that you nowhere initialize your Dictionary objects and that the Dictionary class is abstract. So you could for example use a Hashtable (or if you don't need synchronized access use a faster HashMap instead) for your purpose like this:
testDict = new Hashtable<String, String>();
And make sure to use the correct generic types (the second one has to be the type that your dataVars have)
Maybe this:
al.get(0).get("key1");
Since testDict is at position 0 (first element of your ArrayList) you can retrieve it with get(0)..
Example:
Dictionary firstDict = (Dictionary) al.get(0);
Object key1Data = firstDict.get("key1");
Ps: Generics can greatly improve your code if you are allowed to use it.
Another point is... Why Dictionary and not Map?
Not sure why'd you want keep your dictionaries like that, but you can simply loop over your dictionaries.
public Data getData(String key) {
for(Dictionary dict : al) {
Data result = dict.get(key);
if(result != null)
return result;
}
return null;
}
Well my problem is that in some part of my code I use an arraylist as a key in a hashmap for example
ArrayList<Integer> array = new ArrayList<Integer>();
And then I put my array like a key in a hash map (I need it in this way I'm sure of that)
HashMap<ArrayList<Integer>, String> map = new HashMap<ArrayList<Integer>, String>();
map.put(array, "value1");
Here comes the problem: When I add some value to my array and then I try to recover the data using the same array then the hash map cant find it.
array.add(23);
String value = map.get(array);
At this time value is null instead of string "value1"
I was testing and I discovered that the hashCode changes when array list grows up and this is the central point of my problem, but I want to know how can I fix this.
Use an IdentityHashMap. Then that same array instance will always map to the same value, no matter how its contents (and therefore hash code) are changed.
You can't use a mutable object (that is, one whose hashCode changes) as the key of a HashMap. See if you can find something else to use as the key instead. It's somewhat unusual to map a collection to a string; the other way around is much more common.
Its a weird use case but if you must do it then you can sub class the array and override the hashCode method.
Its a bit of an add thing to try and do in my opinion.
I assume what you are trying to model is a variable length key made up of n integers, and assume that the hash of the ArrayList will be consistent, but I'm not sure that is the case.
I would suggest that you either subclass ArrayList and override the hash() & equals() methods, or wrap the HashMap in a key class.
I'm almost certain you would not want to do that. It's more likely you would want a Map<String, List<Integer>>. However, if you absolutely must do this, use a holder class:
public class ListHolder {
private List<Integer> list = new ArrayList<Integer>();
public List<Integer> getList() {return list;}
}
Map<ListHolder, String> map = new HashMap<ListHolder, String>;
The basic reason: When we use HashMap.put(k, v), it will digit k.hashCode() so that it can know where to put it.
And it also find the value by this number(k.hashCode());
You can see the ArrayList.hashCode() function and it is in the abstract class of AbstractList. Obviously, after we add some object, it will change the haseCode value. So we can not find the value use HashMap.get(K) and there is no element which hashCode is K.
public int hashCode() {
int hashCode = 1;
for (E e : this)
hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
return hashCode;
}
I have set up a HashMap like so:
Map<String, ArrayList<String>> theAccused = new HashMap<String, ArrayList<String>>();
... and I populate this by storing for every name (key), a list of names (value). So:
ArrayList<String> saAccused = new ArrayList<String>();
// populate 'saAccused' ArrayList
...
// done populating
theAccused.put(sAccuser, saAccused);
So now, I want to look through all of the entries in the HashMap and see if (for each 'sAccuser'), the list 'saAccused' contains a certain name. This is my failed attempt so far:
Set<String> setAccusers = theAccused.keySet();
Iterator<String> iterAccusers = setAccusers.iterator();
iterAccusers.next();
ArrayList<String> saTheAccused;
// check if 'sAccuser' has been accused by anyone before
for (int i = 0; i < theAccused.size(); i++) {
saTheAccused = theAccused.get(iterAccusers);
if (saTheAccused.contains(sAccuser)) {
}
iterAccusers.next();
}
... however I'm not sure how the Set and Iterator classes work :/ The problem is that I don't have the "values"... the names... the 'sAccuser's... for the HashMap available.
In a nutshell, I want to iterate through the HashMap and check if a specific name is stored in any of the lists. So how can I do this? Let me know if you need me to go into further detail or clear up any confusion.
Thanks.
In a nutshell, I want to iterate through the HashMap and check if a specific name is stored in any of the lists. So how can I do this?
There's two ways of iterating through the map that might be of interest here. Firstly, you can iterate through all of the mappings (i.e. pairs of key-value relations) using the entrySet() method, which will let you know what the key is for each arraylist. Alternatively, if you don't need the key, you can simply get all of the lists in turn via the values() method. Using the first option might look something like this:
for (Map.Entry<String, ArrayList<String>> entry : theAccused.entrySet())
{
String sListName = entry.getKey();
ArrayList<String> saAccused = entry.getValue();
if (saAccused.contains(sAccuser))
{
// Fire your logic for when you find a match, which can
// depend on the list's key (name) as well
}
}
To answer the broader questions - the Set interface simply represents an (unordered) collection of non-duplicated values. As you can see by the linked Javadoc, there are methods available that you might expect for such an unordered collection. An Iterator is an object that traverses some data structure presenting each element in turn. Typical usage of an iterator would look something like the following:
Iterator<?> it = ...; // get the iterator somehow; often by calling iterator() on a Collection
while (it.hasNext())
{
Object obj = it.next();
// Do something with the obj
}
that is, check whether the iterator is nonexhausted (has more elements) then call the next() method to get that element. However, since the above pattern is so common, it can be elided with Java 5's foreach loop, sparing you from dealing with the iterator itself, as I took advantage of in my first example.
Something like this?
for (List<String> list : theAccused.values()) {
if (list.contains("somename")) {
// found somename
}
}
This should make it work:
saTheAccused = theAccused.get(iterAccused.next());
However, to make your code more readable, you can have either:
for (List<String> values : theAccused.values()) {
if (value.contains(sAcuser)) {
..
}
}
or, if you need the key:
for (String key : theAccused.keySet()) {
List<String> accused = theAccused.get(key);
if (accused.contains(sAccuser)) {
}
}
You need to use the value from Iterator.next() to index into the Map.
String key = iterAccusers.next();
saTheAccused = theAccused.get(key);
Currently you're getting values from the Map based on the iterator, not the values returned by the iterator.
It sounds like you need to do two things: first, find out if a given name is "accused", and second, find out who the accuser is. For that, you need to iterate over the Entry objects within your Map.
for (Entry<String, List<String>> entry : theAccused.entrySet()) {
if (entry.getValue().contains(accused)) {
return entry.getKey();
}
}
return null; // Or throw NullPointerException, or whatever.
In this loop, the Entry object holds a single key-value mapping. So entry.getValue() contains the list of accused, and entry.getKey() contains their accuser.
Make a method that does it:
private String findListWithKeyword(Map<String, ArrayList<String>> map, String keyword) {
Iterator<String> iterAccusers = map.keySet().iterator();
while(iterAccusers.hasNext()) {
String key = iterAccusers.next();
ArrayList<String> list = theAccused.get(key);
if (list.contains(keyword)) {
return key;
}
}
}
And when you call the method:
String key = findListWithKeyword(map, "foobar");
ArrayList<String> theCorrectList = map.get(key);