How to "print" a HashMap in a Hashmap in Java/Android - java

I want to "print" a Hashmap<String, Integer> (let's say Alpha) in a Hashmap<String, Hashmap<String, Integer>> (Beta) and I say "print" because I don't want the "printed" Alpha to change when I re-use Alpha.
For example:
class scratch_2 {
public static void main(String[] args) {
HashMap<String, Integer> Alpha = new HashMap<>();
HashMap<String, HashMap<String, Integer>> Beta = new HashMap<>();
Beta.put("A1", Alpha);
Beta.put("B2", Alpha);
Alpha.put("A", 1);
Alpha.put("B", 2);
System.out.println(Beta); --->print1
Alpha.clear();
System.out.println(Beta); ---->print2
}
}
Result of print1: {A1={A=1, B=2}, B2={A=1, B=2}}
Result of print2: {A1={}, B2={}}
How to set the Beta.put() so that when Alpha is cleared, Beta remains the same?

Here is what you can do to reset a nested HashMap. The value is removed on line 22 and then added back as a new inner hashmap instance. Again, I loop through containingMap and the innerMap getting each map. Once I have a value to reset I call the reset function.
import java.util.*;
import java.lang.*;
public class Collections {
public HashMap<String, HashMap<String, Integer>>
createMap(String beta, String alpha, int m, HashMap<String,
Integer> innerStructure, HashMap<String, HashMap<String,
Integer>> containingStructure) {
while(m>0) {
innerStructure.put(beta, m);
m--;
}
containingStructure.put(alpha, innerStructure);
return containingStructure;
}
public void reset(HashMap<String, HashMap<String, Integer>>
map, int x) {
HashMap<String, Integer> betaMap = new HashMap<String, Integer>();
for(Map.Entry<String,HashMap<String,Integer>> entry: map.entrySet()) {
System.out.println("Key before is:" + entry.getKey());
if(entry.getValue() instanceof Map) {
for(Map.Entry<String, Integer> mapEntry: entry.getValue().entrySet()) {
if(mapEntry.getValue() == x) {
entry.getValue().remove(x);
map.put(entry.getKey(), betaMap);
}
}
}
}
}
public void print(HashMap<String, HashMap<String, Integer>> map) {
for(Map.Entry<String,HashMap<String,Integer>> entry: map.entrySet()) {
System.out.println("Key is:" + entry.getKey());
if(entry.getValue() instanceof Map) {
for(Map.Entry<String, Integer> mapEntry: entry.getValue().entrySet()) {
System.out.println(mapEntry.getKey());
}
}
}
}
public static void main(String[] args) {
Collections collections = new Collections();
HashMap<String, Integer> innerStructure = new HashMap<>();
HashMap<String, HashMap<String, Integer>> containingStructure = new HashMap<>();
containingStructure = collections.createMap("B1", "A1", 4, innerStructure, containingStructure);
collections.reset(containingStructure, 2);
collections.print(containingStructure);
}
}
It really doesn't change the Beta with put it is a matter of evaluating each entry and making sure it is a new HashMap type being used in it's place. I think this should help.

As #Andreas said, I should have created a new instance of Alpha by assigning it like Alpha = new HashMap<>(); when I no longer needed it. I can then re-use it without affecting Beta.

Related

looping through iterator returns the same value

I have the issue that my loop does not break and returns the same value
public Map<String, String> getKeysByValue(Map<String, Map<String, Peple>> map, Collection<Peple> value) {
Map<String, String> stringStringMap = new HashMap<>();
int count = 0;
while (value.iterator().hasNext()) {
for (Map.Entry<String, Map<String, Peple>> entry : map.entrySet()) {
for (Map.Entry<String, Peple> entry1 : entry.getValue().entrySet()) {
String verified = value.iterator().next().gerVerfied();
if (verified.equals("true")) {
stringStringMap.put(entry1.getKey(), value.iterator().next().getName());
}
}
}
The problem here is that the same value kets put in the map for every key (value.iterator().next().getName()) always returns the same string
I think the below would be a correct approach for your problem:
public Map<String, String> getKeysByValue(Map<String, Map<String, Peple>> map, Collection<Peple> value) {
Map<String, String> stringStringMap = new HashMap<>();
int count = 0;
Iterator<People> peopleIterator = value.iterator();
while (peopleIterator.hasNext()) {
for (Map.Entry<String, Map<String, Peple>> entry : map.entrySet()) {
for (Map.Entry<String, Peple> entry1 : entry.getValue().entrySet()) {
People people = peopleIterator.next();
String verified = people.gerVerfied();
if (verified.equals("true")) {
stringStringMap.put(entry1.getKey(), people.getName());
}
}
}
You need to store the iterator in a variable.
Consider below simple code :
Collection<String> strings = new ArrayList<>();
strings.add("value1");
strings.add("value2");
strings.add("value3");
strings.add("value4");
while (strings.iterator.hasNext())
{
System.out.println(strings.iterator.next());
}
This will run infinitely and will only print value1, but if you modify the code as below :
Collection<String> strings = new ArrayList<>();
strings.add("value1");
strings.add("value2");
strings.add("value3");
strings.add("value4");
Iterator<String> stringIterator = strings.iterator();
while (stringIterator.hasNext())
{
System.out.println(stringIterator.next());
}
It runs smooth.
You can learn more about iterator here : https://www.geeksforgeeks.org/how-to-use-iterator-in-java/
ALso, I think as you are calling iterator twice without checking hasNext() on the second call, it can throw java.util.NoSuchElementException
You are calling next() twice on that iterator. That moves it ahead and picks up the name of the next People, which might not be verified.
I believe you just want to get the name if it's a verified Peple?
while (value.iterator().hasNext()) {
for (Map.Entry<String, Map<String, Peple>> entry : map.entrySet()) {
for (Map.Entry<String, Peple> entry1 : entry.getValue().entrySet()) {
Peple nextPeple = value.iterator().next();
String verified = nextPeple.gerVerfied();
if (verified.equals("true")) {
stringStringMap.put(entry1.getKey(), nextPeple.getName());
}
}
}
}
Every time you call value.iterator() new Iterator object is created from scratch, pointing to a first element. To avoid it, store first result of calling it into local variable.
Iterator<Peple> it = value.iterator();
while(it.hasNext()){
// your remaiing code
}
This code works fine with the below input:
import java.util.*;
public class Test {
public static void main(String[] ar){
Map<String, People> entry1 = new HashMap<String , People>();
People people1 = new People("true","name1");
People people2 = new People("false","name2");
People people3 = new People("true","name3");
entry1.put("user1", people1);
entry1.put("user2", people2);
entry1.put("user3", people3);
Map<String, People> entry2 = new HashMap<String , People>();
People people4 = new People("true","name1");
People people5 = new People("false","name2");
People people6 = new People("true","name3");
entry2.put("user1", people4);
entry2.put("user2", people5);
entry2.put("user3", people6);
Map<String, Map<String, People>> map2 = new HashMap<String, Map<String,
People>>();
map2.put("set1",entry1);
map2.put("set2",entry2);
Collection<People> strings = new ArrayList<>();
strings.add(people1);
strings.add(people6);
strings.add(people5);
strings.add(people3);
strings.add(people2);
getKeysByValue(map2, strings);
}
public static Map<String, String> getKeysByValue(Map<String, Map<String, People>> map, Collection<People> value) {
Map<String, String> stringStringMap = new HashMap<>();
int count = 0;
Iterator<People> it = value.iterator();
while (it.hasNext()) {
People people = it.next();
for (Map.Entry<String, Map<String, People>> entry : map.entrySet()) {
for (Map.Entry<String, People> entry1 : entry.getValue().entrySet()) {
String verified = people.getVerified();
System.out.println(verified);
System.out.println("Key : "+entry1.getKey() +" Value : "+entry1.getValue().getVerified());
if (verified.equals(entry1.getValue().getVerified())) {
stringStringMap.put(entry1.getKey(), people.getName());
}
}
}
}
System.out.println(stringStringMap);
return stringStringMap;
}
}
People.java
public class People {
String verified;
public People(String verified, String name){
this.verified = verified;
this.name = name;
}
public String getVerified() {
return verified;
}
public String getName() {
return name;
}
String name;
}
Try this:
public Map<String, String> getKeysByValue(Map<String, Map<String, Peple>> map, Collection<Peple> value) {
Map<String, String> stringStringMap = new HashMap<>();
int count = 0;
Iterator<Peple> iterator = value.iterator();
while (iterator.hasNext()) {
Peple p = iterator.next();
for (Map.Entry<String, Map<String, Peple>> entry : map.entrySet()) {
for (Map.Entry<String, Peple> entry1 : entry.getValue().entrySet()) {
String verified = p.gerVerfied();
if (verified.equals("true")) {
stringStringMap.put(entry1.getKey(), p.getName());
}
}
}
}
}

Want to concatenate Value of one map to key of another map

I want to concatenate to the value of one map to key of another map and add them into list.
Compare value on basis of key of first map to value of another map.
e.g:
map1= {37=core__error_code_based, 153=core__app_dialog, 123=core__date}
map2={copy_2=37,button_back=37,button_cancel=153,button_confirm=153}
My approach is in first loop i get the key of map1 and then in second loop iterate the map2 values on basis map1 key.
So that I get the value of map1 and key of map2 and later concatenate in string.
List<String> finalKey=new ArrayList<>();
Iterator<Map.Entry<String,String>> entrySet=map1.entrySet().iterator();
Iterator<Map.Entry<String,String>> pageKey=map2.entrySet().iterator();
while(entrySet.hasNext()){
Map.Entry<String,String> entry = entrySet.next();
Map.Entry<String,String> pageValue = pageKey.next();
while(entry.getKey()==pageValue.getValue()){
finalKey.add(entry.getValue()+"__"+pageValue.getKey());
}
}
I had tried using iterator and entryset to iterate through the both map but not succeed
{core__error_code_based__copy_2,core__error_code_based__button_back,core__app_dialog__button_confirm,core__app_dialog__button_cancel}
Well i achieved this using
public class translatekeyName {
static List<String> finalString = new ArrayList<>();
public static Map<String, String> initialMap() {
Map<String, String> map1 = new HashMap<>();
map1.put("37", "core__error_code_based");
map1.put("153", "core__app_dialog");
return map1;
}
public static Map<String, String> secondMap() {
Map<String, String> map2 = new HashMap<>();
map2.put("copy_2", "37");
map2.put("button_back", "37");
map2.put("button_cancel", "153");
map2.put("button_confirm", "153");
return map2;
}
public List<String> concatenateString(Map page, Map source) {
Map<String, String> moduleKey = page;
Map<String, String> pageKey = source;
List<String> temp;
Iterator<Map.Entry<String, String>> entrySet = page.entrySet().iterator();
Iterator<Map.Entry<String, String>> pageKeyset = source.entrySet().iterator();
for (String value : moduleKey.keySet()) {
temp = getallKeys(source, value);
String tempValue = moduleKey.get(value);
for (int i = 0; i < temp.size(); i++) {
tempValue += "__" + temp.get(i);
finalString.add(tempValue);
}
}
return finalString;
}
static <K, V> List<K> getallKeys(Map<K, V> mapOfWords, V value) {
List<K> keylist = null;
if (mapOfWords.containsValue(value)) {
keylist = new ArrayList<>();
for (Map.Entry<K, V> entry : mapOfWords.entrySet()) {
if (entry.getValue().equals(value)) {
keylist.add(entry.getKey());
}
}
}
return keylist;
}
public static void main(String[] args) {
translatekeyName obj = new translatekeyName();
obj.concatenateString(initialMap(), secondMap());
System.out.println(finalString);
}
}

I am trying to sort a HashMap by Value, but the results i am getting is pretty awkward. Can anyone help me identify the reasons for it [duplicate]

This question already has answers here:
TreeMap sort by value
(13 answers)
Closed 7 years ago.
This is the code to sort HashMap by Value.
public class LongestChain
{
public static void main(String[] args)
{
String words[] = new String[]{"a","b", "c", "ca","ba","bca","bda","bdca"};
System.out.println(longestChainOfWords(words));
}
public static int longestChainOfWords(String words[])
{
Map<String, Integer> map = new HashMap<String, Integer>();
for(String a:words)
{
map.put(a, a.length());
}
System.out.println(map);
Map sortedMap = sortByValue(map);
System.out.println(sortedMap);
return sortedMap.size();
}
public static Map<String, Integer> sortByValue(Map<String, Integer> unsortedMap)
{
Map<String, Integer> sortedMap = new TreeMap<String, Integer>(new ValueComparator(unsortedMap));
sortedMap.putAll(unsortedMap);
return sortedMap;
}
}
class ValueComparator implements Comparator
{
Map<String, Integer> map;
public ValueComparator(Map<String, Integer> map)
{
this.map = map;
}
public int compare(Object keyA, Object keyB)
{
Comparable valueA = map.get(keyA);
Comparable valueB = map.get(keyB);
System.out.println(keyA+" keyA "); System.out.println(keyB+" keyB ");
return valueA.compareTo(valueB);
}
}
Output is like this. I was expecting 8 elements in sortedMap too. Why the behavior is like this?
{ca=2, bda=3, ba=2, b=1, c=1, a=1, bdca=4, bca=3}
{b=1, ca=2, bda=3, bdca=4}
4
Because you let the TreeMap think it sorts keys. And if the key is equal the no new value will be put inside. As you have 4 different values, so you can find 4 results in your list.
What you can do is improve the compare - method so equal values will be ordered by their keys:
class ValueComparator implements Comparator<String> {
Map<String, Integer> map;
public ValueComparator(final Map<String, Integer> map) {
this.map = map;
}
#Override
public int compare(final String keyA, final String keyB) {
final Integer valueA = this.map.get(keyA);
final Integer valueB = this.map.get(keyB);
System.out.println(keyA + " keyA ");
System.out.println(keyB + " keyB ");
final int compared = valueA.compareTo(valueB);
if (compared != 0) {
return compared;
} else {
return keyA.compareTo(keyB);
}
}
}

Java hashmap iterator

I want to make the method removeValue( "a", "x").
It must delete all keys and values between the letters. For example:
{1=a,2=b,3=c,5=x} ->> {1=a,5=x}
I tried with equals and iterator but I don't know how to write it.
public class CleanMapVal {
public static void main(String[] args) throws Exception {
Map<String, String> map = new HashMap<String, String>();
map.put("1", "a");
map.put("2", "b");
map.put("3", "c");
map.put("4", "w");
map.put("5", "x");
System.out.println( map );
for (Iterator<String> it = map.keySet().iterator(); it.hasNext();)
if ("2".equals(it.next()))
it.remove();
System.out.println(map);
}
public static <K, V> void removeValue(Map<K, V> map) throws Exception {
Map<K, V> tmp = new HashMap<K, V>();
for (Iterator<K> it = map.keySet().iterator(); it.hasNext();) {
K key = it.next();
V val = map.get(key);
if (!tmp.containsValue(val)) {
tmp.put(key, val);
}
}
map.clear();
for (Iterator<K> it = tmp.keySet().iterator(); it.hasNext();) {
K key = it.next();
map.put((K) tmp.get(key), (V) key);
}
}
}
Try the following code.I'm using treemap to maintain the order and then iterating to remove the elements.
Map<Integer, String> map = new TreeMap<Integer, String>();
map.put(1, "a");
map.put(2, "b");
map.put(3, "c");
map.put(4, "w");
map.put(5, "x");
ArrayList<Integer> intList = new ArrayList<Integer>();
for (Iterator<Integer> it = map.keySet().iterator(); it.hasNext();) {
int key = 0;
if (it.next() == 1) {
while(true) {
key = it.next();
if(key==5)break;
intList.add(key);
}
}
}
//removing from the map in separate loop to avoid concurrent modification exception
for (int i : intList) {
map.remove(i);
}
System.out.println(map.size()); //2
First of all, a HashMap never keeps the orders of the Object which are put in it. So you need to use LinkedHashMap which maintains its insertion order.
For removal of Object you need to make use of Iterator
Map testMap = new LinkedHashMap<Integer, String>(); If your key is of any other type except Integer change it accordingly.
So for your requirement, you can use the below code :-
public static void testKey(Map<Integer, String> testMap, String startValue,
String endValue) {
if(!testMap.containsValue(startValue) || !testMap.containsValue(endValue))
return; // if start/end value is not present in Map then no change at all
Iterator<Map.Entry<Integer, String>> iter = testMap.entrySet()
.iterator();
boolean deleteFlag = false;
while (iter.hasNext()) {
Map.Entry<Integer, String> entry = iter.next();
if (endValue.equalsIgnoreCase(entry.getValue())) {
deleteFlag = false;
}
if (deleteFlag)
iter.remove();
if (startValue.equalsIgnoreCase(entry.getValue())) {
deleteFlag = true;
}
}
}
public static void main(String[] args) {
Map m = new LinkedHashMap<Integer, String>();
m.put(1, "a");
m.put(2, "b");
m.put(3, "c");
m.put(5, "x");
System.out.println("before : "+m);
removeValue(m, "a", "x");
System.out.println("after : "+m);
}
Output
before : {1=a, 2=b, 3=c, 5=x}
after : {1=a, 5=x}
Using an Iterator allows you to remove entries on the fly.
public void removeRange(Map<Integer, String> map, String from, String to) {
// Walk each entry.
for (Iterator<Map.Entry<Integer, String>> it = map.entrySet().iterator(); it.hasNext();) {
// What is the value?
String v = it.next().getValue();
if (v.compareTo(from) > 0 && v.compareTo(to) < 0) {
// In the specified range! Remove it.
it.remove();
}
}
}
public void test() {
Map<Integer, String> map = new HashMap<>();
map.put(1, "a");
map.put(2, "b");
map.put(3, "c");
map.put(4, "w");
map.put(5, "x");
System.out.println("Before:" + map);
removeRange(map, "a", "x");
System.out.println("After:" + map);
}
prints
Before:{1=a, 2=b, 3=c, 4=w, 5=x}
After:{1=a, 5=x}
If you are using Java 8 you can also stream and filter a Map.
public <K, V> Map<K, V> filter(Map<K, V> map, Predicate<Map.Entry<K, V>> filter) {
return map.entrySet()
.stream()
// Filter out the unwanted ones.
.filter(filter)
// Fold back into a new Map.
.collect(Collectors.toMap(
(Map.Entry<K, V> e) -> e.getKey(),
(Map.Entry<K, V> e) -> e.getValue()));
}
public Map<Integer, String> removeRangeWithStream(Map<Integer, String> map, String from, String to) {
return filter(map,
(Map.Entry<Integer, String> e) -> e.getValue().compareTo(from) <= 0 || e.getValue().compareTo(to) >= 0);
}

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

Categories