while loop inside for loop not working - java

I have a HashMap.
Map<String,String> lhm = new HashMap<String,String>();
lhm.put("Zara", "biu");
lhm.put("Mahnaz", "nuios");
lhm.put("Ayan", "sdfe");
lhm.put("Daisy", "dfdfh");
lhm.put("Qadir", "qwe");
I want to sort that hashmap according to the sequence which is given in properties file.Actually that property entry will be having the keys in some order.My property entry will looks like this
seq=Ayan,Zara,Mahnaz,Qadir,Daisy
What I have tried towards this is
Map<String,String> lhm = new HashMap<String,String>();
Properties prop=new Properties();
prop.load(new FileInputStream("D:\\vignesh\\sample.properties"));
// Put elements to the map
lhm.put("Zara", "biu");
lhm.put("Mahnaz", "nuios");
lhm.put("Ayan", "sdfe");
lhm.put("Daisy", "dfdfh");
lhm.put("Qadir", "qwe");
// Get a set of the entries
Set<Entry<String, String>> set = lhm.entrySet();
// Get an iterator
Iterator<Entry<String, String>> iter = set.iterator();
// Display elements
String sequence=prop.getProperty("seq");
System.out.println("sequence got here is "+sequence);
String[] resultSequence=sequence.split(",");
for(int j=0;j<resultSequence.length;j++)
{
while(iter.hasNext()) {
Map.Entry me = (Map.Entry)iter.next();
String res=(String) me.getKey();
if(res.equals(resultSequence[j]))
{
System.out.println("values according with the sequence is "+lhm.get(resultSequence[j]));
}
}
}
The output which I'm getting after this is
sequence got here is Ayan,Zara,Mahnaz,Qadir,Daisy
values according with the sequence is sdfe
My expected output is
values according with the sequence is sdfe
values according with the sequence is biu
values according with the sequence is nuios
values according with the sequence is qwe
values according with the sequence is dfdfh
It is working for the first iteration in my for loop.After that it exits from my for loop also.What I'm missing here??Thanks for reading.

It's not working because you never reset your iterator. You only match the string on your first run. Try putting the iterator inside the loop, to get a new one for every iteration, like this:
for(int j=0;j<resultSequence.length;j++)
{
Iterator<Entry<String, String>> iter = set.iterator();
while(iter.hasNext()) {
....
}
}

You are complicating your task too much. In fact, you are just printing your values in sorted order, but not actually sorting them. Also, that's a pathetic way to implement sorting. You are iterating over your map as much number of times as there are strings in your sequence (Currently it's 5).
You should use a TreeMap instead, if you want to sort your keys. Here, you will need to pass custom Comparator, which will compare based on value in your property file.
Suppose you have order in a string:
String order = "Ayan,Zara,Mahnaz,Qadir,Daisy";
then your comparator would look like:
Comparator<String> comparator = new Comparator<String>() {
#Override
public int compare(String key1, String key2) {
return order.indexOf(key1) - order.indexOf(key2);
}
};
The comparator compares each key in the TreeMap based on it's index in the order string.
Now just pass this comparator to the overloaded TreeMap constructor.
SortedMap<String,String> lhm = new TreeMap<String,String>(comparator);
Now, whatever you insert in the map, will be sorted according to the order defined in property file.
To iterate over the map, you can use enhanced for loop:
for(Entry<String, String> entry : lhm.entrySet()) {
System.out.println(entry.getValue());
}

You should get iterator for each iteration of for loop:
...
for(int j=0;j<resultSequence.length;j++)
{
// Get an iterator
Iterator<Entry<String, String>> iter = set.iterator();
while(iter.hasNext()) {
...

Use a TreeMap. This allows you to write a custom comparator for sorting the entries.

HashMap does not save any order, I think you should use LinkedHashMap that iterates in same order that values were inserted.

I think that you don't need iterate with the while loop, once you get the ordered array with the keys from the properties file is enough to do this:
for (String key:resultSequence) {
String value = lhm.get(key);
System.out.println("values according with the sequence is "+ value);
}

Iterate over the keys of your property file. For each of them, get the element in your map, if it exists.

Your while loop only get executed only once , because the iterator doesn't hold any more values after it reached the last element . Instead of while iterator use
for each loop Or else create a new iterator inside for loop and try

Well as the other answers have shown your error which is not reseting the iterator, let me propose another way of doing what you are trying to achieve.
If you want to go through the entire list, intead of using an iterator and writing the usual while(iter.hasNext()){} loop you may want to consider using a for loop as in the following example :
Map<String,String> lhm = new HashMap<String,String>();
// Put elements to the map
lhm.put("Zara", "biu");
lhm.put("Mahnaz", "nuios");
lhm.put("Ayan", "sdfe");
lhm.put("Daisy", "dfdfh");
lhm.put("Qadir", "qwe");
for(Entry<String, String> e : lhm.entrySet()) {
// do something as the for loop iterates through your map.
// e being the current element.
}

Related

android: How to send LinkedHashMap to a URL which is not of a fixed size

I have a LinkedHashMap that I want to send to the URL and then get values from it using php.
This is my HashMaP:
for(int i=1;i<=object.length();i++){
cartData.put(i,String.valueOf(object.getString(String.valueOf(i))));
}
As you can see the size of "cartData" is not fixed and it depends on the size of the object. I want to know how I can each value of the LinkedHashMap to the url dynamically?
Please help!
Pass the map myMap.keySet() and myMap.entrySet() seperately and rebuild the map on the client.
Use the for each Loop over your HashMap, suppose i have hashmap named myHashMap then i can use for each loop to iterate through all HashMap
For dynamically get it until end of the hashmap you can use HashMap's hasNext() method it will iterate through end of hashmap.
for(Integer key : myHashMap.keySet() ){
String value = myHashMap.get(key);
}
Or you can do this ,
Collection c = myHashMap.values();
//obtain an Iterator for Collection
Iterator itr = c.iterator();
//iterate through LinkedHashMap values iterator
while(itr.hasNext())
{
//get the String value here by key
}

How do I store this data in Java?

I want a dictionary of values. The keys are all strings. Each key corresponds with some sort of list of strings. How do I make a list of strings for each key and update that accordingly? I'll explain:
I have a loop that is reading lines of a word list. The words are then converted into a string code and set as keys in the dictionary. Here is an example of the string code/word relationship.
123, [the]
456, [dog]
328, [bug]
...
However, my program keeps looping through the word list and eventually will run into a word with the same code as "the", but maybe a different word, lets say "cat". So I want the list to look like:
123, [the, cat]
456, [dog]
...
How do I get it to make an arraylist for every key that I can then add to on the fly when needed? My end goal is to be able to print out the list of words in that list for a called code (.get())
You can make a HashMap. In your case
HashMap<Integer, ArrayList<String>> works fine.
Like it has already been said, a MultiMap seems to be what you need. Guava that was already suggested and it's a good option. There is also and implementation from commons-collections you can use.
From commons-collections documentation:
MultiValuedMap<K, String> map = new MultiValuedHashMap<K, String>();
map.put(key, "A");
map.put(key, "B");
map.put(key, "C");
Collection<String> coll = map.get(key); // returns ["A", "B", "C"]
You can always implement your own MultiMap if you don't want to use an external library. Use a HashMap<String,List<String>> to store your values and wrap it with your own put, get and whatever other methods you see fit.
It sounds like you want a Multimap from the Guava library.
You can also go the route of using a Map<Integer, List<String>>, but then you will need to manually handle the case where the list is null (probably just allocate a new list in that case).
You can use a HashMap that links each id to a list of strings:
Map<String, List<String>> dictionary = new HashMap<String,List<String>>();
Now let's say you read two Strings: id and word . To add them to your dictionary, you can first verify if your id has already been read (using the containsKey() method)- in which case you just append the word to the list corresponding to that id - or, if this is not the case, you create a new list with this word:
//If the list already exists...
if(dictionary.containsKey(id)) {
List<String> appended = dictionary.get(id);
appended.add(word); //We add a new word to our current list
dictionary.remove(id); //We update the map by first removing the old list
dictionary.put(id, appended); //and then appending the new one
} else {
//Otherwise we create a new list for that id
List<String> newList = new ArrayList<String>();
newList.add(word);
dictionary.put(id, newList);
}
Then whenever you want to retrieve your list of strings for a certain id you can simply use dictionary.get(id);
You can find more information on HashMaps on the Java documentation
I assumed you didn't want repeats in your list so I used Set instead.
Map<String,Set<String>> mapToSet = new HashMap<>();
List<String []>keyvals = Arrays.asList(new String[][]{{"123","the"},{"123","cat"}});
for(String kv[] : keyvals) {
Set<String> s = mapToSet.get(kv[0]);
if(null == s) {
s = new HashSet<String>();
}
s.add(kv[1]);
mapToSet.put(kv[0], s);
}

Pull out the a spefic "rank" from an HashMap not yet sorted which also contains different values but same key or better same count;

I have this HashMap containing words and the count for each word from a given text file;
{word=1, word2=1, word3=2, word4=1, word5=1, word6=4, word7=1, word8=1};
i was following your suggestion in other topics; but i have notice that if use fro example sorted Collections and i search for a specific KEY which could be 1 in this case it only return me one word while instead can return more values for same key;
the point is between all the collections:
Lists
Maps
ArrayLists
Trees
HashMaps
HashTables
which is the most advisable to use?
on my Class the user will input an int and that int will correspond to the 1st or 2nd or 3rd or 4th and so on..... words used in the files base on the count and occurences;
it's challenging
so far i have managed to store in hashmap and eventually order it in a Tree by Desc Key; so first element will be the greater; but still the algorithm needs more sense;
ps. i do not expect solution or pieces of codes but a good input to start ... a very good advise or direction best to follow;
Maps, by nature, store (will return) only one element per key. That means that if you'll store [key:1, val:a] and then store again [key:1, val:2]. The second insertion will override the first and when you'll "get" key:1 the returned result will be b.
You can, however, to store a List per key. This list can store all the value values per the same key.
So we'll declare the map that we'l use as follows:
Map<String, LinkedList<String>> map = new HashMap<>();
This is how insert should look like:
public void insert(String key, String value){
List<String> values = map.get(key);
if (values == null){ // this is the first time we use this key
values = new LinkedList<String>(); // so we need to create a new values List
}
values.add(value);
map.put(key, values)
}
the "get" is pretty straightforward:you get the list of values and if it's not null - iterate the values and print/do whatever you want with them.
public List<String> get(String key){
return map.get(key);
}
If I understand you correctly, you have a Map<String,Integer> map; which maps words to their frequencies, and now you want to look up words by frequency.
Create a new map that Map<Integer,List<String>> and fill it using the first map:
Map<Integer,List<String>> reverseMap = new HashMap<>();
for (Map.Entry<String,Integer> entry : map.entrySet()) {
List<String> list = reverseMap.get(entry.getValue());
if (list == null) {
reverseMap.put(entry.getValue(), list = new ArrayList<>());
}
list.add(entry.getKey());
}
You will get a map like:
java.util.HashMap[3] {
1=[word2, word4, word, word5, word7, word8]
2=[word3]
4=[word6]
}
In this map, each key is the frequency, each value is a list of words having that frequency.
Edit: To pull out the words having the second-most used frequency ("rank 2"), generate a list of the most used frequencies:
List<Integer> frequencies = new ArrayList<>(reverseMap.keySet());
Collections.sort(frequencies, Collections.reverseOrder());
Then:
System.out.println(reverseMap.get(frequences.get(2 - 1)));
Or, to sort the entire map in descending order of frequency (4, 2, 1), declare it as a TreeMap instead of a HashMap, with a reverseOrder comparator:
Map<Integer,List<String>> reverseMap = new TreeMap<>(Collections.reverseOrder());

How to get element position from Java Map

I have this Java Map:
Can you tell me how I can get the 6-th element of the Map?
private static final Map<String, Users> cache = new HashMap<>();
is this possible? Or I have to use another Java collection?
Though a bit late to answer. But the option is to use LinkedHashMap: this map preserves the order according to insertion of elements, as everyone has suggested. However, As a warning, it has a constructor LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder) which will create a linked hash map whose order of iteration is the order in which its entries were last accessed. Don't use this constructor for this case.
However, if I needed such functionality, i would extend it and implement my necessary function to re-use them in OOP way.
class MyLinkedMap<K, V> extends LinkedHashMap<K, V>
{
public V getValue(int i)
{
Map.Entry<K, V>entry = this.getEntry(i);
if(entry == null) return null;
return entry.getValue();
}
public Map.Entry<K, V> getEntry(int i)
{
// check if negetive index provided
Set<Map.Entry<K,V>>entries = entrySet();
int j = 0;
for(Map.Entry<K, V>entry : entries)
if(j++ == i)return entry;
return null;
}
}
Now i can instantiate it and can get a entry and value either way i want:
MyLinkedMap<String, Integer>map = new MyLinkedMap<>();
map.put("a first", 1);
map.put("a second", 2);
map.put("a third", 3);
System.out.println(map.getValue(2));
System.out.println(map.getEntry(1));
Output:
3
a second=2
HashMap doesn't grantee the order. If you concern about order you should use LinkedHashMap
Map<String, Users> orderedMap=new LinkedHashMap<>();
Now when you put an element it will keep the order what you put.
If you want to get 6th element, now you can do it since you have your elements in order.
orderedMap.values().toArray()[5]// will give you 6th value in the map.
Example
Map<String, String> orderedMap=new LinkedHashMap<>();
orderedMap.put("a","a");
orderedMap.put("b","b");
System.out.println(orderedMap.values().toArray()[1]); // you will get b(value)
System.out.println(orderedMap.keySet().toArray()[1]); // you will get b(key)
}
A HashMap does not maintain the order of the elements inserted in it. You can used a LinkedHashMap instead which maintains the order of the elements inserted in it.
Though you need to note that even a LinkedHashMap has no such method which would give the element at a particular index. You will have to manually iterate through the entries and extract the element at the 6th iteration.
With guava's Iterables
Iterables.get(map.entrySet(),6);
The HashMap has no defined ordering of keys.It's Unordered.
You can use LinkedHashMap which will store your keys in order of insertion.You can retrieve them by calling keySet().
HashMaps do not preserve ordering:
LinkedHashMap which guarantees a predictable iteration order.
Example
public class Users
{
private String Id;
public String getId()
{
return Id;
}
public void setId(String id)
{
Id = id;
}
}
Users user;
LinkedHashMap<String,Users> linkedHashMap = new LinkedHashMap<String,Users>();
for (int i = 0; i < 3; i++)
{
user = new Users();
user.setId("value"+i);
linkedHashMap.put("key"+i,user);
}
/* Get by position */
int pos = 1;
Users value = (new ArrayList<Users>(linkedHashMap.values())).get(pos);
System.out.println(value.getId());
According to documentation, HashMap is a Hash table based implementation of the Map interface. This implementation provides all of the optional map operations, and permits null values and the null key. (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.
That's why it is not wise to use this kind of Collection.
UPDATE:
Based on #Prateek implementation of LinkedHashMap I would suggest something like:
LinkedHashMap<String,User> linkedHashMap = new LinkedHashMap<String,User>();
// or LinkedHashMap<String,User> linkedHashMap = new LinkedHashMap<>(); //for java 7+
linkedHashMap.put("1",userObj1);
linkedHashMap.put("2",userObj2);
linkedHashMap.put("3",userObj3);
/* Get by position */
int pos = 1; // Your position
User tmp= (new ArrayList<User>(linkedHashMap.values())).get(pos);
System.out.println(tmp.getName());
A HashMap doesn't have a position. You can iterate through its KeySet or EntrySet, and pick the nth element, but it's not really the same as a position. A LinkedHashMap does have a position, since it has a predictable iteration order.
You need to use a LinkedHashMap in order to be able to tell the order of the inserted elements. HashMap is not capable of doing so.
There is no Order in HashMap. You can obtain the list of may keys using map.keySet() but there's no guarantee the key set will be in the order which you add it in. Use LinkedHashMap instead of HashMap It will always return keys in same order (as insertion)
Correct!!
you will have to use other collection for getting values on index(position).
You can use ArrayList
If the ordering is to mean anything significant, you could consider using a SortedMap.
Concrete implementation: TreeMap
Use LinkedHashMap instead of HashMap It will return keys in same order (as insertion) when calling keySet().
For mare detail about LinkedHashMap see this
For example to get the element from specific index
Create a new list from your values and get the value based on index.
LinkedHashMap<String, List<String>> hMap;
List<List<String>> l = new ArrayList<List<String>>(hMap.values());
l.get(6);

How can I extract ArrayList from HashMap and loop through it in Java?

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);

Categories

Resources