Iterate Map in Java - java

Entry which needs to compare with the List and get the value from Map which is not there is the List.
for (Map.Entry<String, Object> entry : itemObj.entrySet())
{
System.out.println(entry.getKey());
for (ItemProcessVO processVO : itemDetails2){
if (entry.getKey().equalsIgnoreCase(processVO.getAccount())){
String account = processVO.getAccount();
lstAccVO.add(account);
}
}
}
This is the code i have used.I have Map of entry.getKey() has 6 Values while itemDetail2 has only 5 elements.I need to display only the missing account after comparing.

Simply add an else-statement to your if clause that stores that account in a local variable. Then after your for loops you can do whatever with that.
Hint: you can use loop over Map#keySet() instead of Map#entrySet() and bypass the entries that way.

In the provided example you compared the key with the account, simply use the else- statement to find the missingAccounts to iterate after this loop over them.
List<ItemProcessVO> missingAccounts= new ArrayList<>();
for (Map.Entry<String, Object> entry : itemObj.entrySet())
{
System.out.println(entry.getKey());
for (ItemProcessVO processVO : itemDetails2){
if (entry.getKey().equalsIgnoreCase(processVO.getAccount())){
String account = processVO.getAccount();
lstAccVO.add(account);
}else{
missingAccounts.add(account)
}
}
}

Below code should do the trick. It uses case insensitive comparison and prints remaining keys in the end, more explanation is in comments:
public static void main(String[] args) throws IOException {
Map<String, Object> itemObj = new HashMap<>(); //Your Map
List<ItemProcessVO> itemDetails2 = new ArrayList<>();// Your list
//First, get all the keys of the map
Set<String> keys = new HashSet<>(itemObj.keySet());
//Now, iterate through list and remove the matching items
for(ItemProcessVO processVO : itemDetails2){
String key = pop(keys, processVO.getAccount());
//If key is not null then remove it
if(null != key){
keys.remove(key);
}
}
//Now, iterate through remaining keys and print the values
for(String key : keys){
System.out.println("Missing value " + itemObj.get(key));
}
}
private static String pop(Set<String> set, String key){
if(null == set){
return null;
}else{
for(String element : set){
if(element.equalsIgnoreCase(key)){
return element;
}
}
}
}

Related

Removing Keys from hashmap thru composite key value

Hey guys currently have problem with regards to removing duplicates from hashmap.
Some background:
My hashmap is in this format Map<CompositeKeyBean,ValueBean>.
CompositeKeyBean is in the form (String ID, String hashvalue);
ValueBean is an object.
So if i have a hashmap with values as such:
(ID:1,HashValue:123),Obj1
(ID:1,HashValue:234),Obj1
(ID:1,HashValue:345),Obj1
I need to remove the duplicate keys and only have items with unique IDs. currently I have come up with this, But it does not seem to work, im pretty sure i am doing something wrong.
for (Map.Entry<CompositeKeyBean, ReportDataBean> entry : list.entrySet())
{
String idvalue = entry.getKey().getCompositeKeyList().get(0);
for(int i = 1; i < list.size();i++)
{
if(list.keySet().contains(idvalue))
{
list.remove(i);
}
}
}
My solution for this one would be to declare first an another Map which will be used to hold the number of times that a certain key has appeared in the original Map. For the second time, you can iterate the same map entrySet and remove the duplicates using the declared additional Map as reference.
Map<String, Integer> numberOfInstanceMap = new HashMap<String, Integer>(); //temporary placeholder
for (Map.Entry<CompositeKeyBean, ReportDataBean> entry : list.entrySet())
{
String idvalue = entry.getKey().getCompositeKeyList().get(0);
if(!numberOfInstanceMap.containsKey(idvalue)) {
numberOfInstanceMap.put(idvalue, 1); //initialize the key to 1
} else {
numberOfInstanceMap.replace(idValue, numberOfInstanceMap.get(idValue) + 1); //add 1 to the existing value of the key
}
}
for (Map.Entry<CompositeKeyBean, ReportDataBean> entry : list.entrySet())
{
String idvalue = entry.getKey().getCompositeKeyList().get(0);
Integer i = numberOfInstanceMap.get(idValue);
if(i>1) { //remove duplicate if the key exists more than once
list.remove(idValue);
}
}
If you are expecting duplicate keys, then you can do the following way to handle it while populating the map itself:
Map<String, String> map = new HashMap<>();
if(map.containsKey("ID")){
String oldValue = map.get("ID");
//put logic to merge the value
}else{
map.put("ID","newValue");
}

How to efficiently remove entries from a LinkedHashMap in Java?

I want to remove all entries from a LinkedHashMap that were added after an entry with a given key.
My first try was:
LinkedHashMap<String, SomeObject> var = new LinkedHashMap<String, SomeObject>();
public void removeEntriesAfter(String key) {
boolean deleteEntries = false;
for (String currentKey : var.keySet()) {
if(deleteEntries) {
var.remove(currentKey);
} else {
if(key.equalsIgnoreCase(currentKey)) {
// Do not remove the current entry
deleteEntries = true;
}
}
}
}
But then I received a java.util.ConcurrentModificationException.
My second idea was to first determine the keys, an remove them afterwards.
public void removeEntriesAfter(String key) {
boolean deleteEntries = false;
List<String> listOfEntriesToBeRemoved = new ArrayList<String>();
// Determine entries to be deleted
for (String currentKey : var.keySet()) {
if(deleteEntries) {
listOfEntriesToBeRemoved.add(currentKey);
} else {
if(key.equalsIgnoreCase(currentKey)) {
// Do not remove the current entry
deleteEntries = true;
}
}
}
// Removed selected entries
for (String currentKey : listOfEntriesToBeRemoved) {
var.remove(currentKey);
}
}
That works, but I'm sure there is a more elegant/efficient way of doing this.
To avoid a ConcurrentModificationException you can use an Iterator.
Iterator<String> it = map.keySet().iterator();
while (it.hasNext())
if (it.next().equalsIgnoreCase(currentKey))
break;
while (it.hasNext()) {
it.next();
it.remove();
}
If you wanted the most efficient solution, it would be to go straight to the appropriate entry in the first place. To do this you would have to only ever put lower case keys into the map (rather than putting any old strings and comparing using equalsIgnoreCase). Then, using reflection, you could access the Map.Entry object corresponding to currentKey.toLowerCase() and then, using reflection again, you could follow the links all the way through the map. None of this is possible without reflection because neither the entry corresponding to a key nor the links between entries are exposed through public API. I do not recommend reflection as your code could easily break in the future if the code for LinkedHashMap is changed.

Java compare compare value of hashmap with arraylist

I'm really stucked on this problem. I'm not sure if this logic is possible, is there any other whay to achieve what I want?
I'm creating a HashMap like this.
List<String> data1 = new ArrayList();
data1.add("valid1");
data1.add("valid2");
List<String> data2 = new ArrayList();
data2.add("valid3");
data2.add("valid4");
Map<String,ArrayList> hashList = new HashMap();
hashList.put("one",data1);
hashList.put("two",data2);
So the Output will be like this:
{one=[valid1,valid2], two=[valid3,valid4]}
But what am I doing is, i'm reading a file and compare it to hashmap
Code:
String line;
String[] token;
try {
LineIterator it = FileUtils.lineIterator(file,"UTF-8");
while(it.hasNext()){
line = it.nextLine();
token = StringUtils.split(line,(","));
if(token[1].equalsIgnoreCase( //check if its equal to the value of the hashmap){
System.out.println("Valid");
}
}
}
my file looks like this :
test1,valid1,check1
test2,valid3,check2
So what I want to do is, to check if the "token[1]" is valid to the value of hashmap.
Thank you in advance!
Convert the map to list
List<String> list = new ArrayList<String>(map.values());
Then use
list.contains(token[1])
to check if its equal to the list content which is the value of the hashmap
ArrayList<String> check;
check = your_hash_map.get(token[1]);
if(check != null){System.out.println("Valid");}
If you want to get the valid key for the token, the most expensive way of achieving your goal is iterating over the hash keys than iterating over the array value for that key and check if any string inside it matches your conditional.
It should looks like this:
String getValidKey(String token, Map<String, List<String>> hashList) {
for (String key: hashList.keySet()) {
for (String valid: hashList.get(key)) {
if (valid.equalsIgnoreCase(token)) {
return key;
}
}
}
return null;
}
If you only need to know if the token is valid or not this should be enough:
boolean isValid(String token, Map<String, List<String>> hashList) {
for (List<String> list: hashList.values()) {
for (String valid: list) {
if (valid.equalsIgnoreCase(token)) {
return true;
}
}
}
return false;
}

Java HashMap, get(key) method doesnt work

I'm trying to create a PhoneBook class that uses a HashMap in Java. When I add an entry using the put() method in addContact(), it works fine, but when I try to retrieve values in the searchContact() method, none are returned. I'm not getting null values; HashMap definitely contains the key(s) I am searching for, but the values associated with the key(s) are not being returned. Thank you in advance.
Here is my code:
public class PhoneBookContactsImpl {
private Map<String, List<String>> contactMap = new HashMap<String, List<String>>();
public void addContact(String name, List<String> list) {
contactMap.put(name, list);
//its working fine here
System.out.println(contactMap.get(name));
}
public Map<String, List<String>> getContactMap() {
Set set = contactMap.entrySet();
Iterator i = contactMap.entrySet().iterator();
while (i.hasNext()) {
Map.Entry me = (Map.Entry) i.next();
System.out.println(me.getKey() + " : ");
List<String> nos = (List<String>) me.getValue();
System.out.println("Nos = " + nos + " n ");
System.out.println(nos.size());
}
return contactMap;
}
public List<String> searchContact(String name) throws NoDataFoundException {
if (contactMap.isEmpty()) {
System.out.println("Empty PhoneBook");
throw new NoDataFoundException();
} else {
if (contactMap.containsValue(name))
return contactMap.get(name);
//it doesnt retrieve valur from here
else {
System.out.println("No Entry for Specified Entry");
throw new NoDataFoundException();
}
}
}
}
your if statement is checking if the phonebook has name as a value, so your get is never reached.
Try this:
if (contactMap.containsKey(name))
return contactMap.get(name);
As the other answer points out you should be checking containsKey because name is a key, not a value. But why not make the whole thing much easier:
public List<String> searchContact(String name) throws NoDataFoundException {
List<String> result = contactMap.get(name);
if (result == null) {
// empty map, or no matching value or value is null
throw new NoDataFoundException();
}
}
You are doing:
if (contactMap.containsValue(name))
return contactMap.get(name);
and you need to do:
if (contactMap.containsKey(name))
return contactMap.get(name);

Having a hashmap add 1 for each instance of a string in an array.

My hashmap class is as follows:
public HashMap<String, Integer> getWordCounts() {
HashMap<String, Integer> map = new HashMap<String, Integer>();
String[] quoteOne = getWordArray();
for (String stuff : quoteOne) {
map.put(stuff, +1);
}
return map;
}
As it goes through quoteOne I want it to put each word from the array into the hashmap but for duplicates add 1 to the integer. e.g. "If you see this you are cool" would be put into the hashmap as
if 1
you 2
see 1
this 1
are 1
cool 1
But my code is outting it into the hashmap with you 1. What is wrong?
In your code, for every word you see, you put +1 (the int value of positive 1).
You need to update the value, not override it.
for (String stuff : quoteOne) {
Integer oldVal = map.get(stuff);
if (oldVal == null) {
oldVal = 0;
}
map.put(stuff, oldVal+1);
}
Your for loop will be
for (String stuff : quoteOne) {
if(map.get(stuff) != null){
int i = map.get(stuff);
map.put(stuff,i+1)
}else{
map.put(stuff, 1);
}
}
HashMap replaces values if same key is provided.
From Java doc of HashMap#put
Associates the specified value with the specified key in this map. If the map previously contained a mapping for the key, the old value is replaced.
Try something like this
for(String w : words) {
Integer i = wordCounts.get(w);
if(i == null) wordCounts.put(w, 1);
else wordCounts.put(w, i + 1);
}
for(String i: quoteOne)
map.put(i, (map.get(i)!=null)? map.get(i)+1:1);

Categories

Resources