How to get count the same values from HashMap? - java

How to get count the same values from HashMAP?
HashMap<HashMap<String, Float>, String> HM=new HashMap<HashMap<String,Float>, String>();
HashMap<String, Float> h;
h=new HashMap<String, Float>();
h.put("X", 48.0f);
h.put("Y", 80.0f);
HM.put(typeValuesHM, "Red");
h=new HashMap<String, Float>();
h.put("X", 192.0f);
h.put("Y", 80.0f);
HM.put(typeValuesHM, "Red");
h=new HashMap<String, Float>();
h.put("X", 192.0f);
h.put("Y", 320.0f);
HM.put(typeValuesHM, "Blue");
h=new HashMap<String, Float>();
h.put("X", 336.0f);
h.put("Y", 560.0f);
HM.put(typeValuesHM, "Blue");
The values of my HashMap HM are as follows:
{ {x=48,y=80}=Red,{x=192,y=80}=Red,{x=192,y=320}=Blue,{x=336,y=560}=Blue }
Here,
I want to count the similar values in the HashMap HM.
ie) if i give value equals to "Red" means i want to get count=2.
if i give value equals to "Blue" means i want to get count=2.
How to get count the same values from HashMAP HM?

int count = Collections.frequency(new ArrayList<String>(HM.values()), "Red");

Loop through the entry set and drop all values to a second map, the first maps value as a key, the value will be the count:
Map<String, Integer> result = new TreeMap<String, Integer>();
for (Map.Entry<Map<String, Float>> entry:HM.entrySet()) {
String value = entry.getValue();
Integer count = result.get(value);
if (count == null)
result.put(value, new Integer(1));
else
result.put(value, new Integer(count+1));
}
The result map for your example should be like this:
{"Red"=2, "Blue"=2} // values are stored as Integer objects

The only way you can do it is to iterate through all the elements and count the occurrences:
for(String value: hm.values()) {
if (value.equals(valueToCompare)) {
count++;
}
}

int countValue(String toMatch) {
int count = 0;
for (String v : HM.values()) {
if (toMatch.equals(value)) {
count++;
}
}
return count;
}
Also, it is probably overkill to use a HashMap as the key if you are just storing two values. The built in Point uses int, but it would not be hard to re-implement with float.

Iterator<String> iter = HM.values().iterator();
while(iter.hasNext()) {
String color = iter.next();
if(color.equals("Red")) {
} else if(color.equals("Green")) {
} else if(color.equals("Blue")) {
}
}

Related

How to get and compare the value results of a map<Integer, Integer>

By calling a method ,at my case countInNumbers, is returning results as an array.
System.out.println(countIntInNumbers(Array));
result:
{1=17, 2=10, 3=16, 4=17, 5=13, 6=22, 7=10, 8=15, 9=16, 10=19, 11=11, 12=15, 13=16, 14=13, 15=19, 16=17, 17=13, 18=21, 19=19, 20=15,}
I try to separate the numbers on different table depending their total value.
Example... I want to display the numbers that their total is between 3 and 4 to separate table than the other numbers.
Facing this problem cause the results as you may notice are Map since i am new in Java and I am so confused at this point.
Anyone can suggest from something to start of?
Updated:::
countIntInNumbers method as follows
public static Map<Integer, Integer> countIntInNumbers(int[][] mat) {
Map<Integer, Integer> intOccurences = new HashMap<>();
for (int[] row : mat) {
for (int intInRow : row) {
Integer occurences = intOccurences.get(intInRow);
if (occurences == null) { // first occurrence
intOccurences.put(intInRow, 1);
} else { // increment
intOccurences.put(intInRow, occurences.intValue() + 1);
}
}
}
return intOccurences;
I try to separate the numbers on different table depending their total value. Example... I want to print all numbers that their total is between 3 and 4 to separate table than the other numbers.
We are not sure what you are asking here but if you mean that you want to display the numbers which have a total between 2 numbers then you could do something like:
private void printNumbers(Map<Integer, Integer> intOccurences, int minTotal, int maxTotal){
boolean first = false;
System.out.print("{");
for (Map.Entry<Integer, Integer> entry : intOccurences.entrySet()) {
int total = entry.getValue();
if (total >= minTotal && total <= maxTotal) {
if (first) {
first = false;
} else {
System.out.print(", ");
}
System.out.print(entry.getKey() + "=" + total);
}
}
System.out.print("}");
}
If you are taking about copying the values to a new map then maybe something like:
private Map<Integer, Integer> extractNumbers(Map<Integer, Integer> intOccurences,
int minTotal, int maxTotal) {
Map<Integer, Integer> result = new HashMap<>();
for (Map.Entry<Integer, Integer> entry : intOccurences.entrySet()) {
int total = entry.getValue();
if (total >= minTotal && total <= maxTotal) {
result.put(entry.getKey(), total);
}
}
// not sure if you want to remove the ones from the original map
return result;
}
If you want to compare the value of a map just get it by key. Then since the values of the map are of wrapper Integer you can compare using ==, >=, <= since the Integer equals() method simply compares the int value it wraps with the other Integer's int value. In example:
// Adding some test values to the map
Map<Integer, Integer> map = new HashMap<>();
map.put(1, 5);
map.put(2, 6);
map.put(3, 5);
// Get values by key map.get(key)
// Compare values map.get(key) == map.get(key) or use >=, <=
System.out.println(map.get(1) <= map.get(2)); // true
System.out.println(map.get(1) == map.get(3)); // true
System.out.println(map.get(1) >= map.get(2)); // false
In your countIntInNumbers it seems you are just returning and printing the map by using its toString() method. If I got you right you want to print the keys which values are between 3 and 4. In this case the values are Integer so there will not be any value between 3 and 4 other than the integers themselves.
Okay after seeing your edit, convert your raw matrix to a map and then search for the values you need, and put them into a new map. Something like this:
public static Map<Integer, Integer> countIntInNumbers(int[][] mat) {
Map<Integer, Integer> matConvertedToMap = new HashMap<>();
for(int i=0; i<mat.length; i++)
{
matConvertedToMap.put(mat[i][0], mat[i][1]);
}
Map<Integer, Integer> intOccurences = new HashMap<>();
for (Map.Entry<Integer, Integer> entry : matConvertedToMap.entrySet())
{
if(entry.getValue() == 3 || entry.getValue() == 4)
{
intOccurences.put(entry.getKey(), entry.getValue());
}
}
return intOccurences;
}
Not sure what the comparison really is and what you are expected to return but that should give you a general feeling of how to iterate through the map.

Java: LinkedHashMaps overlaps over themselves

I want to create a copy of linked hash map and then I want to remove all values (from the List) instead of the first entry. Here is what I got:
LinkedHashMap<String, List<Value>> facetsInCategoriesCopy = new LinkedHashMap<>(facetsInCategories);
if (!facets.equals("something")) {
for (List<Value> value : facetsInCategoriesCopy.values()) {
if (value.size() > 1) {
int nbrOfElements = value.size();
for (int i = nbrOfElements-1; i > 0; i--) {
value.remove(i);
}
}
}
}
After this operation it turns out that facetsInCategories are modified too. Why? And how to solve the issue?
Any help would be appreciated.
I don't have a 50 reputation to add a comment. See this answer Assigning Hashmap to Hashmap
Essentially, the copy constructor you used to make the new map has references to the mutable objects i.e. facetsInCategories and will update that as well when you update the facetsInCategoriesCopy map.
The solution would be to instead do a deep copy instead. I have added test code below, I used String instead of Value
//Test for https://stackoverflow.com/questions/27324315/
public static void testStackO_Q_27324315() {
Map<String, List<String>> facetsInCategories = new LinkedHashMap<String, List<String>>();
String[] values = new String[]{"Test1", "Test2", "Test3"};
List<String> valuesList = new ArrayList<String>(Arrays.asList(values));
facetsInCategories.put("Test", valuesList);
Map temp = Collections.unmodifiableMap(facetsInCategories);
LinkedHashMap<String, List<String>> facetsInCategoriesCopy = (LinkedHashMap<String, List<String>>)deepCopy(temp);
String facets = "test_me";
if (!facets.equals("something")) {
for (List<String> value : facetsInCategoriesCopy.values()) {
if (value.size() > 1) {
int nbrOfElements = value.size();
for (int i = nbrOfElements-1; i > 0; i--) {
value.remove(i);
}
}
}
}
System.out.println(facetsInCategories);
System.out.println(facetsInCategoriesCopy);
}
public static <K1, K2, V> Map<K1, List<V>> deepCopy(
Map<K1, List<V>> original){
Map<K1, List<V>> copy = new LinkedHashMap<K1, List<V>>();
for(Map.Entry<K1, List<V>> entry : original.entrySet()){
copy.put(entry.getKey(), new ArrayList<V>(entry.getValue()));
}
return copy;
}

How to iterate a map from another map?

I have this Map where the key is an Integer and the value is another map. I want to know how to iterate through the second map.
private Map<Integer,Map<Integer,Integer>> transition = new HashMap<Integer, Map<Integer, Integer>>();
private Map<Integer,Map<Integer,Integer>> transition = new HashMap<Integer, Map<Integer, Integer>>();
for (Integer outerKey : transition.keySet()) {
Map<Integer, Integer> inner = transition.get(outerKey);
for (Integer innerKey : inner.keySet()) {
Integer value = inner.get(innerKey);
}
}
+1 #angel_navarro Another way is using entry set
Map<Integer, HashMap<Integer, Integer>> map = new HashMap<Integer, HashMap<Integer, Integer>>();
for (Map.Entry<Integer, HashMap<Integer, Integer>> entry : map.entrySet()) {
HashMap<Integer, Integer> submap = entry.getValue();
for (Map.Entry<Integer, Integer> sub_entry : submap.entrySet()) {
System.out.println("Key = " + entry.getKey() + ", Value = "
+ entry.getValue());
}
}
I like this idiom better:
for(Map.Entry<Integer,Map<Integer,Integer>> outer : transition.entrySet()){
Integer outerKey = outer.getKey();
for(Map.Entry<Integer,Integer> inner : outer.getValue().entrySet()){
Integer innerKey = inner.getKey();
Integer innerValue = inner.getValue();
}
}
By the way, I suggest you take a look at Guava's new collection types, e.g., Multimap, for alternatives to nested collections. Maybe they won't fit your use case today, but it's good to know they exist.
private Map<Integer,Map<Integer,Integer>> transition = new HashMap<Integer, Map<Integer, Integer>>();
for(Map.Entry<Integer,Map<Integer,Integer>> entryMap : transition.values())
{
final Integer outerKey = entryMap.getKey();
for (Map.Entry<Integer, Integer> entry : entryMap.getValue().entrySet())
{
final Integer innerKey = entry.getKey();
final Integer innerValue = entry.getValue();
}
}

Printing output of Collection.Max

I have the following code . Collections.Max returns the . How can I show the value of string and integer no By System.out.println() ?
public class SortMapOnKeyExample {
public static void main(String[] args) {
List<String> list=new ArrayList<String>();
list.add("sultan");
list.add("Masum");
list.add("sultan");
list.add("Sorry");
list.add("sultan");
list.add("Masum");
list.add("sultan");
list.add("Tarek");
list.add("sultan");
Set<String> uniques = new HashSet(list);
Map<String, Integer> counts = new HashMap<String, Integer>();
for (String elem : uniques)
{
counts.put(elem, Collections.frequency(list, elem));
}
Collections.max(counts.entrySet(), new Comparator<Entry<String, Integer>>() {
#Override
public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
return (o1.getValue() - o2.getValue());
}
});
}
}
I have tried a lot But could not find out how can I do this ?please help me . The purpose of this code is to find the string that is occurred maximum and also its index ?
Firstly, you code will run in O(n^2) time - each call to Collections.frequency must loop over the entire data, and this is done once for every element. You can easily make this O(n):
final Map<String, Integer> counts = new HashMap<>();
for (final String s : list) {
final Integer c = counts.get(s);
if (c == null) {
counts.put(s, 1);
} else {
counts.put(s, c + 1);
}
}
Now note that you can have more than one item with the same count. You need to sort the entries by value and then print the top ones:
final List<Entry<String, Integer>> entries = new ArrayList<>(counts.entrySet());
Collections.sort(entries, new Comparator<Entry<String, Integer>>() {
#Override
public int compare(final Entry<String, Integer> o1, final Entry<String, Integer> o2) {
return Integer.compare(o2.getValue(), o1.getValue());
}
});
final MessageFormat format = new MessageFormat("{0} has a count of {1,number,integer}");
final Iterator<Entry<String, Integer>> iter = entries.iterator();
final Entry<String, Integer> first = iter.next();
System.out.println(format.format(new Object[]{first.getKey(), first.getValue()}));
while (iter.hasNext()) {
final Entry<String, Integer> entry = iter.next();
if (entry.getValue() != first.getValue()) {
break;
}
System.out.println(format.format(new Object[]{entry.getKey(), entry.getValue()}));
}
First we create a List from the entrySet() of the Map. Next we sort the List - notice the reversed order of the comparison - this means the sort is in descending rather than ascending order. Also note the use of Integer.compare, this is because using a - b to compare is very bad practice as it will overflow if a is large and b is large and negative; while not a problem here it is not a good habit to get into.
Now we take as Iterator of the List and keep printing out elements until we encounter one that is not equal to (must be less than) the count of the first element.
Output:
{sultan=5, Sorry=1, Tarek=1, Masum=2}
sultan has a count of 5
With different data, where we add Test five times also the output becomes:
{Test=5, sultan=5, Sorry=1, Tarek=1, Masum=2}
Test has a count of 5
sultan has a count of 5

Java HashMap losing value on loop iteration

i'm attempting to reorder an List of Maps in alphabetical order. i can see that the "name" String gets filled out with the appropriate value, but groupDataCopy is never updated. as far as i know, using the new operator and calling "put" will place the value in the Map. but I can see that on the following iteration, the ArrayList contains:
{name = null}
i don't know why i'm losing values in my Map List. here is the code:
private void sortByName() {
List<Map<String, String>> groupDataCopy = new ArrayList<Map<String, String>>();
List<List<Map<String, String>>> childDataCopy = new ArrayList<List<Map<String, String>>>();
int groupPos = 0;
int nextNamePos = 0;
String name = null;
while(groupPos<groupData.size()) {
//main loop
int groupDataComparison = 0;
name = null;
while(groupDataComparison<groupData.size()) {
//comparison traversal for group
if(!groupDataCopy.isEmpty()) { //if groupDataCopy has data
if(groupDataCopy.get(groupDataCopy.size()-1).get("name").compareTo(groupData.get(groupDataComparison).get("name")) > 0) { //if the last index of groupDataCopy is alphabetically after (or equal to) last chosen name
if(name==null || groupData.get(groupDataComparison).get("name").compareTo(name) < 0) {
name = groupData.get(groupDataComparison).get("name");
nextNamePos = groupDataComparison;
}
}
} else {
if(name==null || groupData.get(groupDataComparison).get("name").compareTo(name) < 0) {
name = groupData.get(groupDataComparison).get("name");
nextNamePos = groupDataComparison;
}
}
groupDataComparison++;
}
groupDataCopy.add(new HashMap<String, String>());
groupDataCopy.get(groupPos).put("name", name);
childDataCopy.add(new ArrayList<Map<String, String>>());
for(Map<String, String> data : childData.get(nextNamePos)) {
childDataCopy.get(groupPos).add(data);
}
groupPos++;
}
groupData = groupDataCopy;
childData = childDataCopy;
}
Comparator<Map<String, String> comparator = new Comparator<Map<String, String>()
{
public int compare(Map<String, String> o1, Map<String, String> o2)
{
return o1.get("name").compartTo(o2.get("name");
}
}
Collections.sort(groupData, comparator);
Try creating a Comparator that will let you use Collections.sort:
Something like:
Comparator<Map<String, String> comp = new Comparator<Map<String, String>()
{
public int compare(Map<String, String> o1, Map<String, String> o2)
{
//write code to compare values
}
}
After which you can simply do:
Collections.sort(groupData, comp);

Categories