ArrayList<HashMap<String, String>>
arrayListRowsFirst = new ArrayList<HashMap<String, String>>();
Today when i was going through a code, this piece of code struck me for a while. Here are some of my questions over this declaration.
What could be the requirement if one has to append an HashMap into an ArrayList.
What will happen during sorting of arraylist, how it will go, will it take long time.
First off, "generic chaining" in my opinion is a poor practice. I would encourage wrapping the HashMap in a class that encapsulates the data inside, allowing the logic for manipulation to be inside the class, not just strewn about everywhere.
To answer #1, I could think of a number of scenarios. You might have languages for instance, mapping certain constants to other translations. The fact that it says rows first in the identifier makes me think perhaps it's some kind of matrix of data, and that the first String parameter will exist in all the entries of the list (a poor practice indeed.)
Edit: I misunderstood your question, it appears. You would add it like any other entry. See the others' answers for example code. :-)
To answer #2, you won't be able to sort the ArrayList unless you are able to provide a comparator, at which point it's up to you how it's sorted (could be size, could be the value of a particular key, could be Math.random(), it's up to whoever writes the comparator).
There is no "special requirement" to append an HashMap to an ArrayList.
And as neither Map nor HashMap implements Comparable, so if you want to sort the ArrayList, you would have to create your own Comparator.
A sort on a List which contains Map would be exactly the same as a sort on a List wich contains anything else.
What do you mean about "append a HashMap into an ArrayList"? You add HashMaps to the ArrayList the way you add any object to a List
HashMap<String,String> hm = new HashMap<String,String>();
arrayListRowsFirst.add(hm);
You sort the array list like you sort any other - you would need to define a Comparator that compared two HashMaps, and use Collections.sort with that Comparator. How long it takes will depend a lot on how you're comparing the HashMaps.
You would add HashMaps to the ArrayList like you would any other object, using the add() method. Obviously it would need to be of the correct Type, in this case a HashMap of Strings.
You would need to create a comparator so that your HashMaps would be sortable.
The declaration should be
List<Map<String, String>>
1 to append a map into the list, you just do
Map<String, String> map = new HashMap<String, String>();
list.add(map);
2 To sort the list, you would need a way to tell if one Map is "greater than", "less than", or "equal" to another Map. The could or might not take a long time depending on your needs. It doesn't have to take a long time.
Related
I have the following treemap
private TreeMap<Long, HashMap<Long, Entry>> index;
Entry contains:
int tf //count
ArrayList<long> off //positions
For each entry in the treemap, I would like to sort the hashmaps by tf. In the following picture, tf of [3] has a bigger value of tf of [0] so I would like to move it to be at the beggining. How can I do that?
You cannot order a HashMap. Trying to do so breaks the way a HashMap stores and finds the elements added to it
What you are trying to do here (as I understand it) is sorting the treemap by its value, while TreeMap can only sort by its keys. more details here - TreeMap sort by value
You may try writing your own sorting method and store the result of sort in a linkedHashMap instead of Treemap. That way you can be able to access the entries in the exact order you added that to the linkedHashMap.
Note: with each change happening to the original map, you ll need to sort it and move it to a different linkedHashMap. Which is very clumsy.
You may consider using different object model for your program.
I believe the fundamental problem with your question is that HashMaps are not sortable by definition. Secondly, a variable definition that is more generic may prove useful:
private SortedMap<Long, SortedMap<Entry, Long>> index;
Noticed I switched the order of Entry and Long. This is because Maps only sort based on the key. You'd have to either make Entry implement Comparable or provide a custom Comparator when you instantiate that Map.
I have the following code and I'd like to get able to get the first and last element from the Map and assign each to a String.
String result1stElement = null;
String resultLastElement = null;
Map<String, String> result = new HashMap<String, String>();
result = myModel.getSampleResults();
Any ideas.
Thanks in advance.
First of all, Maps are not ordered so you wont really have a first and last element.
However, if you wish to get the first and last element of this anyways you could just get the values and convert this into an array. This isn't really pretty, but it'll work.
Map<String, String> result = new HashMap<String, String>();
result = myModel.getSampleResults();
map.values().toArray()[0]; //First result
map.values().toArray()[result.size()-1]; //Last result
Note: This is not tested with a compiler.
First and last element concepts not applicable to Hash-based structures like HashMap and HashSet.
Insertion or deletion of key may cause element reordering on-the-fly.
I guess your model results is an key-value pairs list, not hash map. In this case element ordering is in place. LinkedHashMap keeps insertion order of elements.
Replace HashMap to LinkedHashMap (and modify .getSampleResults()) to return LinkedHashMap and check this question for futher details Java LinkedHashMap get first or last entry .
HashMap has no such thing as order. From HashMap javadoc:
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.
You'll have to use LinkedHashMap. Take a look at entrySet() method and this question+answer
"toArray" method of Set interface can be used.
But iterating over the entries in the entry set and getting the first and last entry is a better approach.
This example might be helpful:
public static void main(final String[] args) {
final Map<Integer,String> orderMap = new LinkedHashMap<Integer,String>();
orderMap.put(6, "Six");
orderMap.put(7, "Seven");
orderMap.put(3, "Three");
orderMap.put(100, "Hundered");
orderMap.put(10, "Ten");
final Set<Entry<Integer, String>> mapValues = orderMap.entrySet();
final int maplength = mapValues.size();
final Entry<Integer,String>[] test = new Entry[maplength];
mapValues.toArray(test);
System.out.print("First Key:"+test[0].getKey());
System.out.println(" First Value:"+test[0].getValue());
System.out.print("Last Key:"+test[maplength-1].getKey());
System.out.println(" Last Value:"+test[maplength-1].getValue());
}
// the output geneated is :
First Key:6 First Value:Six
Last Key:10 Last Value:Ten
There is no such a thing as a first and last element in a HashMap. This is the price you have to pay for O(1) lookup: internally the implementation will chuck your entries into a list of buckets in no easily identifiable (but deterministic) order. This process puts the Hash in HashMap, and in fact the more chaotic it is, the better the performance.
You can use a TreeMap if you want a map sorted by the natural order of its keys (or a custom comparator) or you can have a LinkedHashMap if you want the elements to be arranged in the order of insertion.
P.s.: even if you choose a Map implementation that maintains some kind of order, calling toArray() just to get the first and last elements is a massive overkill, I wouldn't do it. TreeMap has firstEntry() and lastEntry() methods, and even with LinkedHashMap, it's a lot cheaper to just manually iterate across the elements and keep the first and last one instead of allocating a potentially huge array.
Your comment to #Nikolay's answer shows an important detail of your question that was hidden until now.
So, you want to test a method which uses a HashMap structure for refering to some added objects and you want to test, if this method delivers some ordering in this structure? First added object shall remain at a "first position", last added object at a "last position"?
As the other answers already show, there is no way without refactoring that method. HashMap doesn't deliver any meaningful ordering at all and if that method should deliver some ordering, it is simply broken - implementation is faulty.
Of course, you can write a unit test using the algorithm provided by #Sander. This test will fail most of the time. And this again shows the fact, that the tested method has to be refactured like #Nikolay showed in his answer, for instance.
I couldn't find a better title than that so pardon me for any kind of confusion.
I want to combine two hashmap into one hashmap.I am actually using hashmaps to contain the datas of table where key=coloumName and value= coloumValues.
My code looks something like
HashMap<String, ArrayList> FTMap = table1.getColumn().getColumnValues()
HashMap<String, ArrayList> STMap = table2.getColumn().getColumnValues()
HashMap<String, ArrayList> FinalTableMap = new HashMap()
FinalTableMap.putAll(FTMap)
FinalTableMap.putAll(STMap)
I don't have any problem with column names but the order of coloumvalues are not working after the combining. Since i am using arraylist,i am trying to compare two arraylist and put it in a final arraylist which can be used as the value of the final hashmap.I need some advice or suggestion for this matching between two arraylist.
After you have used addAll to combine your lists, you can use Collections.sort(List, Comparator) to sort your ArrayList. In your Comparator's compare function, you will compare the two objects using the values you wish to sort by (you mentioned serial id?).
See Sort ArrayList of custom Objects by property for a brief example.
I am looking to implement a data structure that would add / render an ordered pair of values. eg.
orderedPair.add(value1, text1)
orderedPair.add(value1, text2)
orderedPair.add(value2, text3, data1)
orderedPair.add(value2, data2)
orderedPair.add(value1, text5)
When I get, I want it to return iteratively as
value1, text1
value1, text2
value2, text3, data1 and so on.
LinkedHashMaps or any variants of HashMaps do not work since they return only the value based on key and what I am trying to get is value, value pairs. Note that neither value / text or data are unique and I may not be able to fetch it based on any keys. Also, i do NOT want a sorted list, I do need an ORDERED list only.
Question is: Is there any data structure in Java that can be used to accomplish this?
I did not come across any that serves this purpose. In which case I am pondering about writing a custom collection that would accomplish this. Any suggestions / help is welcome.
Wrapping the discussion in the comments into an answer, since it seems to be useful to the OP:
Create a class Tuple, which will be your pairs/triples.
Note that this class can be implemented with a fixed number of parameters or as a container that holds a list of objects.
Hold these Tuple objects in a List<Tuple>, and you are done.
You can also implement hashCode(), equals() and make it implement Comparable to this class - and you will be able to use it with other collections such as TreeSet and HashSet.
Just use a Map of Lists, like Treemap
Map<Integer, List<Integer>> content = new Treemap<Integer, List<Integer>>();
if (not content.containsKey(value1)) {
content.put(value1, new LinkedList<Integer>());
}
content.get(value1).add(text1)
This would be the function orderedPair.add
Then for output, traverse the Map and for each entry, write out each item of the corresponding List
Since you want to have it ordered, pass a Comparator to the Treemap constructor.
OK so this is a BIT different. I have a new HashMap
private Map<String, Player> players = new HashMap<String, Player>();
How do I remove last known item from that? Maybe somethign like this?
hey = Player.get(players.size() - 1);
Player.remove(hey);
The problem is, a HashMap is not sorted like a list. The internal order depends on the hashCode() value of the key (e.g. String). You can use a LinkedHashMap which preserves the insert order. To remove the last entry on this you can use an iterator in combination with a counter which compares to the size and remove the last entry.
It's so easy. Try this:
Map<String, Player> players = new LinkedHashMap<String, Players>();
List<String> list = new ArrayList<String>(players.keySet());
map.remove(list.get(list.size()-1));
I'm a little bit confused. First of all, you're saying that you've got a new ArrayList and you're illustrating this with a line that creates a new HashMap. Secondly, does the Player class really have static methods like get(int) and remove(Object)?
HashMap doesn't have a particular order, ArrayList (as any other List) does.
Removing from an ArrayList
If you've got a list of players, then you can do the following:
private List<Player> players = new ArrayList<Player>();
// Populate the list of players
players.remove(players.size() - 1);
Here, I've used the remove(int) method of List, which allows to remove an item at an arbitrary index.
Removing from a HashMap
If you've got a map of players, there's no such thing as "the last item". Sure, you can iterate over the map and one of the items will pop out last, but that doesn't mean anything. Therefore, first you have to find out what you want to remove. Then you can do the following:
private Map<String, Player> players = new HashMap<String, Player>();
// Populate the map of players
// Find the key of the player to remove
players.remove(toRemove);
Here, I've used the remove(Object) method of Map. Note that in order to remove some key-value pair, you have to show the key, not the value.
There's no "first" and "last" in a HashMap. It's unordered. Everything is accessible by its key, not by index.
You cannot delete from HashMap like that. You need to use LinkedHashMap.
Simple, just do something of this effect.
1) Get a keyset iterator;
2) Create a Key somelastKey = null
3) Iterate through the iterator and assigning somelastKey until iterator finishes.
4) finally, do players.remove(somelastKey);
Bear in mind that HashMap is unordered, it depends on Object's hashCode to determine insertion order.
Instead of using HashMap, try using LinkedHashMap which keeps a predictable iteration order.
Hope this helps....
You'll probably have to extend HashMap, override put so that it caches the key, and then create a new method that just removes the key that was cached.
Unfortunately, this will only let you remove the most recently added. If you need to remove the most recently added multiple times (without inserting in-between the removes), you're out of luck.
In that case, I'd probably do the same overrides, just write the keys to a List. So you'd have both a list and a Map.
When adding:
String key; Player value;
lastKey = key;
map.put(key, value);
//...later...
Player lastAdded = map.remove(lastKey);
Other than that there's really no way without using a LinkedHashMap or in some way creating your own wrapper map or extending HashMap.
You shouldn't be using a raw hashmap anywhere because things like this happen.
Get in the habit of wrapping your collections in business logic classes.
See, in your case right now you need to associate these two related variables--your hashmap and a "Last entered" item so you can remove it.
If you need to remove the last item from some other class, you need to pass both items.
Any time you find yourself passing 2 or more items together into more than one API, you are probably missing a class.
Create a new class that contains the hashmap and a "lastAdded" variable. Have put and remove methods that are just forwarded to the hashmap, but the put method would also set the lastAdded variable.
Also be sure to add a removeLast() method.
NEVER allow access to your hashmap outside this class, it needs to be completely private (this is what I mean by wrapped). In this way you can ensure it doesn't get out of sync with the lastAdded variable (also completely private).
Just to reiterate getters and setters for these variables would be a terrible idea (as they are with nearly all actual OO code).
You will quickly find a bunch of other methods that NEED to be in this class in order to access data inside your hashmap--methods that never felt right in their current location. You will probably also notice that those methods always have an additional parameter or two passed in--those parameters should probably be members of your new class.
Once you get in the habit of doing actual OO design (via refactoring in this case), you'll find your code MUCH more manageable. To illustrate this point, if you find later that you need multiple levels of "delete last", it will be TRIVIAL to add to your class because it will be extremely clear exactly what methods can modify your hashtable and where your new "stack" of lastItems should be located--in fact it's probably a 2 line code change.
If you do not make this wrapper class, various locations will each have code to set "lastAdded" when they add code to the hashtable. Each of those locations will have to be modified, some may be in other classes requiring you to pass your new stack around with the hashtable. It will be easier to get them out of synch if you forget to change one location.