iterate with max key value so that it will replace max string value. first My code is
HashMap<String, String> mapp=new HashMap<String, String>();
mapp.put("ab","blue");
mapp.put("abc","black");
mapp.put("abcd","pink");
for (Iterator it = alltyp.iterator(); it.hasNext();) {
String finalstring = (String) it.next();
Iterator it1=mapp.entrySet().iterator();
while(it1.hasNext())
{
Map.Entry pairs = (Map.Entry) it1.next();
String key_ = (String) pairs.getKey();
String value_ = (String) pairs.getValue();
finalstring = finalstring.replaceAll(key_, value_);
}
}
I want to iterate with max key value means key value "abcd" should iterate first then "abc" then "ab".
Here is an example using Collections.max(). You can also pass a comparator if you want a custom ordering.
HashMap<String, String> mapp=new HashMap<String, String>();
mapp.put("ab","blue");
mapp.put("abc","black");
mapp.put("abcd","pink");
// find max key alphabetically
String maxKey = Collections.max(mapp.keySet());
Comparator<String> strLenCmp = new Comparator<String>() {
#Override
public int compare(String o1, String o2) {
return Integer.compare(o1.length(), o2.length());
}
};
// find max key by key length
String longKey = Collections.max(mapp.keySet(), strLenCmp);
Edit: added example with custom Comparator
Use Generics, get rid of the casting. That will tidy up your code a lot.
You will need a custom comparator to do the sorting.
Once you have the comparator you have two choices:
Option 1:
Create an ArrayList, dump all the keys from the map into it.
Sort the ArrayList, iterate over the sorted ArrayList.
Option 2:
Use a TreeMap to store the data.
Try using the TreeMap instead of HashMap it has the method for getting the last entry which will give you the entry which has the highest value of key. Even in TreeMap if you pass your custom Comparator then it will be sorted in a way that you will get the key with max value first so you don't have to worry about it.
TreeMap - lastEntry
Refer this link, and lastEntry method.
Related
I defined a hashmap as follows
HashMap<String, List<String>> hashmap = new HashMap<String, List<String>>();
I can get its content out by doing
Set<Map.Entry<String, List<String>>> keys = hashmap.entrySet();
for (Map.Entry<String,List<String>> entry : hashmap.entrySet()) {
String key = entry.getKey();
List<String> thing = entry.getValue();
System.out.println (key);
System.out.println (thing);
}
However, I would like to know:
How could I retrieve its content to an ordinary string?
Is it possible to access the strings on the fly? (without doing (1)) I mean, the same way you do string[0], etc
Where is the length of the list stored?
Assuming that String key = "str"; exists in the map. You can:
int mapSize = hashmap.size(); // get the map's size
List<String> list = hashmap.get("str"); // get a list for a key
String first = hashmap.get("str").get(0); // get a string in a list
int listSize = hashmap.get("str").size(); // get the size of a list
char ch = hashmap.get("str").get(0).charAt(0); // get a char of a string in a list in the map
Instead of manually getting the set of keys, how about using the keySet() method on the HashMap object from Java?
Use of keySet() looks like:
Set<String> keys = hashmap.keySet();
For the third bullet, see the size() method.
I've a SortedMap which have items like:
1=abc
2=xyz
3=abc
Values can be duplicate.
I want to display the value-set on screen in the sorted manner. i.e.
myListMap
abc
abc
xyz
To sort the Map, I'm using comparator:
public class SortMapByValueComparator implements Comparator<String> {
Map<String, String> mInputMap;
/**
* Constructor.
*
* #param inputMap
*/
public SortMapByValueComparator(Map<String, String> inputMap) {
mInputMap = inputMap;
}
#Override
public int compare(String lhs, String rhs) {
String string1 = mInputMap.get(lhs);
String string2 = mInputMap.get(rhs);
return string1.compareToIgnoreCase(string2);
}
}
And then passing the Map to this comparator like:
SortMapByValueComparator sortMapByValueComparator = new SortMapByValueComparator(myListMap);
SortedMap<String, String> sortedMapByValue = new TreeMap<String, String>(sortMapByValueComparator);
sortedMapByValue.putAll(myListMap);
Now, issue is when I call SortMapByValueComparator, it removes duplicate values. How can I avoid it?
PS - I want to use Map only.
The problem is that compareToIgnoreCase() is returning 0 when two strings are equal, and returning zero is merging the keys as it is explained here. Implement your compare in a way that zero is not returned, it should work fine.
if(string1.compareToIgnoreCase(string2) >= 0)
return 1;
else
return -1;
I would change the whole approach and go with something simpler:
// initializing your Map
// not sure if key set is Integer or String but it doesn't really matter here
Map<Integer, String> tm = new TreeMap<Integer, String>();
tm.put(1, "abc");
tm.put(2, "xyz");
tm.put(3, "abc");
// getting the values as List (not Set, so duplicates allowed)
List<String>values = new ArrayList<String>(tm.values());
System.out.printf("Unsorted values: %s%n", values);
// sorting the values with natural (lexicographic) order...
Collections.sort(values);
System.out.printf("Sorted values: %s%n", values);
Output
Unsorted values: [abc, xyz, abc]
Sorted values: [abc, abc, xyz]
I have a HashMap which is populated with String and Integer:
Map<String, Integer> from_table;
from_table = new HashMap<String, Integer>();
Next i want to get all the keys of items which there value (the Integer) is above x.
For example all the keys which their value is over 4.
Is there a fast method for doing that?
Thnaks!
public static void printMap(Map mp) {
for(Map.Entry pairs : mp.entrySet()) {
if(pairs.getValue() >= 4)
{
System.out.println(pairs.getKey());
}
}
}
Well, iterate over the key-value pairs and collect keys where values meet the criteria
//collect results here
List<String> resultKeys= new ArrayLIst<String>();
//hash map iterator
Iterator<String> it = from_table.keySet();
while(it.hasNext()) {
//get the key
String key= it.next();
/get the value for the key
Integer value= from_map.get(key);
//check the criteria
if (value.intValue() > x) {
resultKeys.add(key);
}
}
Not in standard Java. Guava has method called filter doing exactly this as a one-liner (+ the predicate).
As the above solution states there is nothing faster than just looping through, but an alternative solution would be to edit the function to put something in the map and have it check if there are 4 or more items, if there are it adds it to a new list with only objects with a count of more than 4
I have a Hashtable in java like below and I'm trying to get the key that has the minimum value. Obviously I can iterate through all the elements to find it but is there an easier way to do it?
Hashtable<Object, Integer> hash= new Hashtable<Object, Integer>();
Using a Hashtable, no. But you could instead use a TreeMap.
A Red-Black tree based NavigableMap implementation. The map is sorted
according to the natural ordering of its keys, or by a Comparator
provided at map creation time, depending on which constructor is used.
It has a method firstKey() which provides the exact functionality you want.
Grr, values, not keys. No, then you will need to iterate.
I'd say in that case you should use a separate Map (Multimap?) to store the reverse association.
Map<Object, Integer> hash= new Hashtable<Object, Integer>();
SortedSetMultimap<Integer, Object> reverse = TreeMultimap.create();
whenever you put key, value something into hash, also put value, key into reverse.
then retrieve the lowest value using reverse.keySet().first()
(this solution requires Guava)
Instead of iterating yourself you can use library function Collections.min(Collection,Comparator) over entrySet().
SAMPLE
public static void main(String[] args) {
HashMap<String,Integer> map = new HashMap<String,Integer>();
map.put("A", 1);
map.put("B", 2);
map.put("C", 3);
System.out.println(
Collections.min(map.entrySet(), new Comparator<Map.Entry<String,Integer>>() {
#Override
public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
return o1.getValue().intValue() - o2.getValue().intValue();
}})
.getKey()
);
}
It looks like the easiest way to do it is in fact iterating over the elements. If the Hashtable name is hash:
Object minObj= null;
int min= Integer.MAX_VALUE;
for(Map.Entry<Object, Integer> x: hash.entrySet()){
if(x.getValue() < min){
min= x.getValue();
minObj= x.getKey();
}
}
Minimum value can be findout in this way as well,
Hashtable h = new Hashtable();
h.put(10, "aaa");
h.put(1, "aab");
h.put(12, "aabwqkjdg");
Set set = h.keySet();
TreeSet treeSet= new TreeSet();
treeSet.addAll(set);
System.out.println("Last :"+treeSet.first());
I just took example of keys as integer.
I have the following Map:
Map<String, List<String>> map = new HashMap<String, List<String>>();
which is filled with pairs of keys and values.
For example: key = student name and value = family members names.
I want to sort the map by the size of the list of strings. I have tried implementing Comparator with a TreeMap but I got an error so I switched back to HashMap. Any ideas?
You should use the HashMap unordered, and then each time you want to order, put all the values of the HashMap into a TreeMap, using a Comparator that has the HashMap as a variable.
Then, for each key you compare, you get the value of the HashMap (the list) and check the list size. So you compare by the list sizes, returning -1, 0 or 1 depending on the case.
Once you finish what you need, you discard that TreeMap.
If you try to use only a TreeMap, then you'll see that you are ordering the keys according to a value that is not a property of such key. In this case, the length of the value (a list). So, there may exist a function that increases the length of the list, and the TreeMap won't even notice.
Some code:
public class ListSizeComparator implements Comparator<String> {
private final Map<String, List<String>> map;
public ListSizeComparator(final Map<String, List<String>> map) {
this.map = map;
}
#Override
public int compare(String s1, String s2) {
//Here I assume both keys exist in the map.
List<String> list1 = this.map.get(s1);
List<String> list2 = this.map.get(s2);
Integer length1 = list1.size();
Integer length2 = list2.size();
return length1.compareTo(length2);
}
}
The solution is more or less identical to https://stackoverflow.com/a/8897384/869736, but all you need to do is write a Comparator that compares lists by their length.
Comparator<List<String>> lengthComparator = new Comparator<List<String>>() {
public int compare(List<String> a, List<String> b) {
return a.size() - b.size();
// size() is always nonnegative, so this won't have crazy overflow bugs
}
};
and then just use the solution outlined there.
I see three choices here:
Sort the map contents every time you need - if it's not too often that it's OK.
In addition to the map store other auxiliary structure with desired order, for example TreeMap<Integer, List<String>> (key - number of family members, value - list of students).
May be you don't need at all your map as you described it and following map will be sufficient: TreeMap<Integer, Map<String, List<String>>> (key - number of family members, value - part of your original map containing students with number of family members equal $key).