Iterate Hash Map - java

I have an hashmap declared as
private HashMap testMessages = null;
I will be storing string values in both key and value part of the hashmap retrieved from oracle table.
I am not concerned about the hashmap keys. I want to retrieve the hashmap values alone and check whether string variable filename is prefixed with one of the hash map value and return true if it's same. I want to ensure that hash map values are not null and empty.
function (string filename)
{..
loop thru hashmap values
check whether the variable file name is prefixed with one of the hashmap values if so
return true
otherwise
return false
}
hashmap example:
key1,prod
key2,test
key3,dummy
filename example:
test123_20012010.csv
should return true since the file name is prefixed with one of the hashmap values
How can i do it?

for (String prefix : map.values()) {
if (filename.startsWith(prefix)) {
return true;
}
}
return false;
It should be noted that this is linear time in the number of entries in the map in the worst case. If you have multiple filename that you want to do the check for, it's much better to preprocess the prefixes and build something like a patricia trie and other fast dictionary-like data structures.

Here's a brute force approach to iterate over the hash map values and check whether filename begins with the value.
// generics version
private HashMap<String, String> testMessages = buildMap();
for (String v : testMessages.values()) {
if (filename.startsWith(v) {
// found a map value that starts the file name
}
}
// alternative non-generics version
private HashMap testMessages; // assigned somewhere
for (Object v : testMessages.values()) {
if (filename.startsWith((String) v) {
// found a map value that starts the file name
}
}

leeched from leepoint.net
public static void iterate_over_hashmap(Map mp) {
Iterator it = mp.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pairs = (Map.Entry)it.next();
System.out.println(pairs.getKey() + " = " + pairs.getValue());
}
}
You have to treat each entry as a key/value pair and iterate over those as a single entity. Then you cast it into Map.Entry and then you can read both separately

function(String fileName)
{
for(String value : hashMap.values())
{
if(fileName.startsWith(value))
return true;
}
return false;
}

Related

Adding values under same key HashMap in Java [duplicate]

This question already has answers here:
Increment an Integer within a HashMap
(13 answers)
Closed 10 months ago.
I'm new to HashMaps, and I was wondering if there was a way to add values together if they have the same key.
For example, when I have the key 'a' and the value is 20 and later on I use the key 'a' again and the value is 10 the value should now be 30.
I don't know how I would check if the Value already is in the HashMap and then use the same value again. The adding part could be done with just a variable that copies the current value and adds the new one, I guess.
I am guessing you want a hashmap for character vs integer and want to add the integer to already present value in case the value is present.You can do something like below:
public hashMapImpl(char ch, int number){
Map<Character,Integer> map = new HashMap<>();
if(map.containsKey(ch)){
map.put(ch, map.get(ch)+number);
}
else{
map.put(ch,number);
}
}
Where ch will be your key and number will be something that you want to store at particular key.
you can use compute method to add/sum a value in case a key exists, or create a new entry in case it doesn't.
Map<String, Integer> map = new HashMap<>();
String myKey = "a";
Integer myValue = 10;
map.compute(myKey, (key, value) -> {
if (value == null)
return myValue;
else
return value + myValue;
}
);
System.out.println(map);
map.compute(myKey, (key, value) -> {
if (value == null)
return myValue;
else
return value + myValue;
}
);
System.out.println(map);
Outputs:
a={10}
a={20}
Of course, putting this compute logic inside a method will make you code cleaner :)
I will use an example class called HashMapExamle to explain this.
Inside the class I will create a HashMap called bigHashMap assuming that was your initial hashMap with prior data.
I also have a main method to call the method that will solve your problem. I have named the method bigHashMap. So for starters, i have initialized our prior HashMap named bigHashMap and initialized wit with some new key-value pairs.
I will printout the value of the HashMap. I will then add a value with the same key, in this case food with the value 15, by calling the hashMapValueAdd method I have created and passing the key(food) and value(15) to it.
The concept of the method is:
Check if the HashMap contains the key.
if it has it, it will get the value with that ky and add the new value to it. it will then replace the value at the key with the new value.
If the key is not found in the hashmap then the new key-value pair will just be inserted.
class HashMapExample {
private static HashMap<String, Integer> bigHashMap;
public static void main(String[] args) {
bigHashMap = new HashMap<>();
// Add test data
bigHashMap.put("food", 200);
bigHashMap.put("transport", 20);
bigHashMap.put("entertainment", 40);
System.out.println("Data before : \n" + bigHashMap);
hashmapValueAdd("food", 15);
System.out.println("Data after : \n" + bigHashMap);
}
private static void hashmapValueAdd(String key, int value) {
// Check if hashMap contains the given key
if (bigHashMap.containsKey(key)) {
// Get previous value with the same key
int valueWithSameKey = bigHashMap.get(key);
// Increment the value with incoming value
int newValue = valueWithSameKey + value;
// Put updated value into HashMap
// bigHashMap.put(key, +value);
bigHashMap.replace(key, newValue);
} else {
// Put the current key since it does not exist in the HashMap
bigHashMap.put(key, value);
}
}
}
I hope this solves your problem.
You can check out these HashMap explanations to get a better understanding.
Java HashMap - W3Schools
Java MAp - Jakob Jenkov
Java HashMap replace()
Update the Value Associated With a Key in a HashMap

Remove a value from a List nested in a Map

I've got a HashMap which contains an ArrayList as value. I want to check if one of the lists contains an object and remove that object from the list. How can I achieve that?
I've tried using some for loops, but then I get a ConcurrentModificationException. I can't get that exception away.
My hashmap:
Map<String,List<UUID>> inAreaMap = new HashMap<String, ArrayList<UUID>>();
I intend to check if the ArrayList contains the UUID I've got, and if so, I want to remove it from that ArrayList. But I don't know the String at that position of the code.
What I already tried:
for (List<UUID> uuidlist : inAreaMap.values()) {
for (UUID uuid : uuidlist) {
if (uuid.equals(e.getPlayer().getUniqueId())) {
for (String row : inAreaMap.keySet()) {
if (inAreaMap.get(row).equals(uuidlist)) {
inAreaMap.get(row).remove(uuid);
}
}
}
}
}
There is a more elegant way to do this, using Java 8:
Map<String, ArrayList<UUID>> map = ...
UUID testId = ...
// defined elsewhere
// iterate through the set of elements in the map, produce a string and list for each
map.forEach((string, list) -> {
// as the name suggests, removes if the UUID equals the test UUID
list.removeIf(uuid -> uuid.equals(testId));
});
try with the iterator.
inareamap.iterator().. and.. iterator.remove()
If you have Java 8, the solution of camaron1024's solution is the best. Otherwise you can make use of the fact that you have a list and iterate through it backwards by index.
for(ArrayList<UUID> uuidlist : inareamap.values()) {
for(int i=uuidlist.size()-1;i>=0;i--) {
if (uuidlist.get(i).equals(e.getPlayer().getUniqueId()))
uuidlist.remove(i);
}
}
Here the easy solution.
UUID key = ... ;
for(Map.Entry<String,ArrayList<UUID>> e : hm.entrySet()){
Iterator<UUID> itr = e.getValue().iterator();
while(itr.hasNext()){
if(itr.next() == key)
itr.remove();
}
}

How Can I Search on A Treeset to Find Values that Are Either Greater or Less Than or Case Insensitive?

I am trying out creating an in-memory database solution. Either HashMap or TreeSet. I know how I can search for a value using contains, and if this was a normal database situation this would be easier. But if I'm trying to search for a value by case-insensitive or a numerical value that is either greater or less than, how would I go about that in this case?
Here is my last name method, but it is just a simple contains, if it is is case insensitive it's not found
case 4:
Scanner input4 = new Scanner(System.in);
System.out.println("Search Last Name ");
String retLn = input4.nextLine();
if(employeeKey.containsKey(retLn))
{
EmpManager searchedEmp = employeeKey.get(retLn);
System.out.println(searchedEmp);
System.out.println("");
}
else
{
System.out.println("No Last Name Found");
System.out.println("");
}
You may use a TreeMap with Custom Comparator.
When you want a case-insensitive comparison:
new TreeMap<String,V>(String.CASE_INSENSITIVE_ORDER);
When you want an Integer based comparison:
new TreeMap<Integer,V>(Comparator.naturalOrder());
Or just use default comparator:
new TreeMap<Integer,V>();
For finding all entries greater or lesser than a value use headMap(), tailMap() or subMap()
You can override the containsKey() method in your HashMap definition.
For example:
HashMap<String, Integer> map = new HashMap<String, Integer>() {
#Override
public boolean containsKey(Object key) {
for (String s : this.keySet()) {
String keyString = (String) key;
if (keyString.equalsIgnoreCase(s))
return true;
}
return false;
}
};
As per your current solution, just ensure whenever you're adding to the Map that you turn the keys to lowerCase to make it case-insensitive, which then makes it easier to compare against user input later on e.g.
if(employeeKey.containsKey(retLn.toLowerCase())) // considering the keys inside the map are all lowercase
if you later want to search based on some given range, then you could do this:
map.forEach((key, value) -> {
if(key.equalsIgnoreCase(retLn) && value > someValue && value < someValue){
// access the value here
}
});

Getting intersection of a keys of a map

This is my map
Map<String,Set<Integer>> transactions = new HashMap<String,Set<Integer>>();
This is the Set of string
Set<String> check_set
Now question is how to make this method
Set<Integer> getIntersection(Map<String,Set<Integer>> transactions, Set<String> check_set)
Which will return intersection of all the Set of integers corresponding to the keys in check_set.
If the MAP is
tea=[1,3,5,7,9],
milk=[2,3,6,7,9],
sugar=[1,4,6,8,9]...
and if check_set is {"tea","milk"} then the method should return values which are present in both tea and milk i.e {3,7,9}. Or if it has {"milk","sugar"} then it should return {6,9}. if it has all three {"sugar","milk",tea"} then it should return {3,9}.
I understand I need to use retainAll function to get intersection. But how to formulate a logic to check all sets of integer in map and get their intersection.
EDIT : must use a copy of the first set in map (thanks to Bohemian)
In pseudo-code, you could have
Init result set to null to know it is still not initialized
Loop for each key in check_set
if result is null then result = map{key} // take first set
else result = intersection(result, map{key}) // and keep on intersecting
That gives in java
Set<Integer> result = null;
for (String key: check_set) {
if (result == null) {
result = new HashSet<Integer>(map.get(key));
}
else {
result.retainAll(map.get(key));
}
}
private static Set<Integer> getIntersection(Map<String, Set<Integer>> transactions, Set<String> checkSet) {
Iterator<String> iterator = checkSet.iterator();
// create a copy of the original set
Set<Integer> result = new HashSet<>(transactions.get(iterator.next()));
while (iterator.hasNext()) {
result.retainAll(transactions.get(iterator.next()));
}
return result;
}

Hashmap contains key

I found this program in my text book, which basically counts the occurence of each string in the String array tst.
public class Test {
private static HashMap<String, Integer> mp = new HashMap<String, Integer>();
public static void main(String[] args) {
String[] tst = new String[] { "ABC", "DEF", "DEF", "DEF","ABC", "DEF", "ABC" };
checkMap(tst);
}
public static void checkMap(String[] str) {
for (String st : str) {
if (!mp.containsKey(st)) {
mp.put(st, 1);
}
else {
Integer ct = mp.get(st);
if(ct!=null)
{
ct++;
mp.put(st, ct);
}
}
}
for (Map.Entry<String, Integer> entry : mp.entrySet()) {
System.out.println(entry.getKey() + " ocurrs " + entry.getValue()+ " times");
}
}
}
The output for the code is -
ABC ocurrs 3 times
DEF ocurrs 4 times
My question is in the if/else statement here -
if (!mp.containsKey(st)) {
mp.put(st, 1);
}
else {
Integer ct = mp.get(st);
if(ct!=null)
{
ct++;
mp.put(st, ct);
}
}
When we haven't put any entries inside the hashmap (the hashmap is empty), on what basis does this work? Apologies if this is a very basic question, but I found no answer anywhere online that explains this. I am confused with what is written in the if/else loop.
Also, this line here -
Integer ct = mp.get(st);
How can we get the value to which the key is mapped when infact the hashmap is actually empty? I am trying to relate this to an array - If you query elements of an array once its created, but not initialized, it throws a null pointer. Someone, please explain how this works for a hashmap. Once again, apologies for asking such a basic question.
Well, in this line you check whether the map contains a key
if (!mp.containsKey(st)) {
Since there is a ! before the expression, this means "if the map does not contain a key". After that, "then" block follows where you insert a key in the map with value 1 (since it does not exist).
Otherwise if the key does exist (the else block), you take the value for that key, increment it (ct++) and add it again to the map for the same key.
Let me just say that the null check (if(ct!=null)) is not necessary for this code.
General remark on this question:
How can we get the value to which the key is mapped when infact the hashmap is actually empty?
If you try to get something from the HashMap for a key that is not present in the map, the map returns null. That is true for any key you try to get from an empty map.
Can you please explain what this means though - Integer ct = mp.get(st);
map.get(key) returns a value that is stored for that key. The map itself is a collection of key-value pairs, which means: for each key there is one value in the map. So to get the value stored for that key you invoke map.get(key). If you store map.put("ABC", 10) the map will return 10 for map.get("ABC").
This is because of containsKey function checks if the hashMap contains particular key.
If the HashMap is mpty and you try to do a get on non existant key you will get a null value
st is get here by the for (String st : str) loop. It has nothing to do with the HashMap.
if (!mp.containsKey(st)) {
This tests if the HashMap does not contain the key st. If there are no items it obviously can not contain the key. Then in the else block it uses mp.get(st), which will now always succeed because it has been checked that mp contains st (actually, it does not not contain it).
The null check if (ct == null) is here because if for some reason the map contained null for the key in question. That however shouldn't be possible if the code only puts integers to the map and tests for the existence of the key, so the null check coulb be removed.
The test:
if (!mp.containsKey(st))
tests if there is no entry in the map by that key.
It is therefore logical that in the else branch, the entry exists and has a non null value... Which makes the ct == null test redundant.
And when the value exists, the code get()s the existing value, adds 1 to it (in fact it creates a new Integer but that's another story) and put()s back the new value.
Note that that code mixes autoboxing and non autoboxing. mp.put(st, 1) does autoboxing; behind the scenes it really does mp.put(st, new Integer(1)).
Similarly:
Integer ct = mp.get(st);
ct++;
is really:
Integer ct = mp.get(st);
Integer tmp = new Integer(ct.intValue() + 1);
ct = tmp;
The null check is not necessary. Either the key is contained in the map and its value is not null, or it is not contained in the map.
The reason we can be confident about the value never being null is that the map (and all its contents) is defined and used in the method, and there's no opportunity for a null to get it there.
Although the get() method will return null if passed a key that it doesn't contain, that will never happen with this code.
Anyway, the code is inelegant: All those lines can be expressed as one simple line:
mp.put(mp.containsKey(st) ? mp.get(st) + 1 : 1);

Categories