Java 8 Streams hashmap - java

I need perform an hashmap iteration using Java 8 streams. I need to iterate over an hashmap. Check whether a particular key ("new") does not have null or empty values, copy that value to a variable (String val1) of type string. Then again check for another key for ex:"old" and then copy that value to a variable (String val2) of type string and call the main method where i need to send these 2 values (val1, val2). This has to be done with in hashmap iteration. Can you please help me on this.
The code:
map1.entrySet()
.stream()
.filter(s -> {
if (s.getKey().contains("abc") && !s.getValue().equals("") && s.getValue()!=null) {
String val1 = s.getValue;
if (s.getKey().contains("bb")) {
String val2 = s.getValue(); //call the function
callFunction(val1,val2);
}
}
else {
}
});

Need to be done using Java 8
for(Map.Entry e : map1.entrySet()) {
if(e.containsKey("new")&& !e.getValue().equals("")){
String val1 = (String) e.getValue();
if(e.containsKey("old")&& !e.getValue().equals("")){
String val2 = (String) e.getValue();
//call the function-- This is boolean
if(validateMethod(val1, val2)){ // if true
Map<String, String> map2 = new HashMap<>();
map2.putAll(e);
}
}
}
}

You need to look for particular keys : new and old so you don't need to iterate over the entries of the map, because if the keys exist they will be unique.
get the value of the specific keys, if they don't exist, keep en empty String
do your stuff with these values
Map<String, String> map1 = ...;
String v1 = map1.getOrDefault("new", "");
String v2 = map1.getOrDefault("old", "");
Map<String, String> map2 = new HashMap<>();
if(!v1.isEmpty() && !v2.isEmpty() && validateMethod(v1, v2)){
// do your stuff
}
You might put the check for isEmpty in your validateMethod rather than in an if

Try it with this:
yourMap.entrySet().stream()
From this point, you can manage. Stream consists of Entry<Key,Value> so you can check whatever you want to.

Related

how to iterate and compare over Hashtable<String, Map<String, Set<String>>> in java

I have a structure like below ,
Key: active-csr-HA-profile & Value: {sapd-outside=[outside], sapd-extra4=[extra4], sapd-extra3=[extra3], sapd-inside=[inside]}
Key = sapd-outside, Value = [outside]
Key = sapd-extra4, Value = [extra4]
Key = sapd-extra3, Value = [extra3]
Key = sapd-inside, Value = [inside]
Key: standby-csr-HA-profile & Value: {sapd-outside=[outside], sapd-extra4=[extra4], sapd-extra3=[extra3], sapd-inside=[inside]}
Key = sapd-outside, Value = [outside]
Key = sapd-extra4, Value = [extra4]
Key = sapd-extra3, Value = [extra3]
Key = sapd-inside, Value = [inside]
the above if of format Hashtable<String, Map<String, Set<String>>>
I want to compare if sapd-outside of active-csr-HA-profile is same as one of the keys of standby-csr-HA-profile. So compare each key of active-csr-HA-profile to each key of standby-csr-HA-profile.
I looked some similar questions but what i am working out is not solving the purpose.
As already mentioned in the comments, the Hashtable is considered obsolete. Its replacement is HashMap. If you wish make HashMap synchronized the same way the Hashtable does, use the Collections::synchronizedMap decorator on it.
The structure of your Hashtable looks a bit unclear. I guess the following structure matches your one the best and I base my solution on it.
Hashtable<String, Map<String, Set<String>>> map = new Hashtable<>();
Map<String, Set<String>> activeCsrHAProfile = new HashMap<>();
activeCsrHAProfile.put("sapd-outside", new HashSet<>(Arrays.asList("outside")));
activeCsrHAProfile.put("sapd-extra4", new HashSet<>(Arrays.asList("extra4")));
activeCsrHAProfile.put("sapd-extra3", new HashSet<>(Arrays.asList("extra3")));
activeCsrHAProfile.put("sapd-inside", new HashSet<>(Arrays.asList("inside")));
Map<String, Set<String>> standbyCsrHAProfile = new HashMap<>();
standbyCsrHAProfile.put("sapd-outside", new HashSet<>(Arrays.asList("outside")));
standbyCsrHAProfile.put("sapd-extra4", new HashSet<>(Arrays.asList("extra4")));
standbyCsrHAProfile.put("sapd-extra3", new HashSet<>(Arrays.asList("extra3")));
standbyCsrHAProfile.put("sapd-inside", new HashSet<>(Arrays.asList("inside")));
map.put("active-csr-HA-profile", activeCsrHAProfile);
map.put("standby-csr-HA-profile", standbyCsrHAProfile);
In case my structure differs a bit from yours, there would be no problem to amend the solution in order to match your structure - the principle is the same.
Set<String> sapdOutsideOfActiveCsrHAProfile = map.get("active-csr-HA-profile")
.get("sapd-outside");
map.get("standby-csr-HA-profile").entrySet()
.stream()
.filter(i -> i.getValue().containsAll(sapdOutsideOfActiveCsrHAProfile))
.forEach(e -> System.out.println("Found at: " +
"key=" + e.getKey() + ", value=" + e.getValue()));
.filter(i -> i.getValue().containsAll(..) filters those entris which values Set<String> contains all of the required Strings.
.forEach(..) gives a consumer performing an action over all the matching results.
In case you need the boolean representing whether the match has occurred or not, do:
boolean matches = map.get(..).entrySet().stream().filter(..).findFirst().isPresent();
As mentioned in the comments, HashTable is a debatable choice. Regardless of the implementation you choose, you could create your own class to manage the messy stuff:
public class CustomMap extends Hashtable<String, Map<String, Set<String>>> {
public CustomMap() {
super();
}
public boolean compareEntries(String key1, String key2) {
if (!this.containsKey(key1) || !this.containsKey(key2) || this.get(key1).size() != this.get(key2).size())
return false;
for (String innerKey : this.get(key1).keySet()) {
if (!this.get(key2).containsKey(innerKey)) {
return false;
}
final Set<String> setA = this.get(key1).get(innerKey);
final Set<String> setB = this.get(key2).get(innerKey);
if (!setA.containsAll(setB) || !setB.containsAll(setA)) {
return false;
}
}
return true;
}
}
I took the assumption there could be more entries in your table and you'd want to compare specific entries.
You can iterate through a map with its entry set:
Hashtable<String, Map<String, Set<String>>> table = new Hashtable();
for (Map.Entry<String, Map<String, Set<String>>> entry : table.entrySet()) {
String key = entry.getKey();
Map<String, Set<String>> map = entry.getValue();
for (Map.Entry<String, Set<String>> mapEntry : map.entrySet()) {
String mapKey = mapEntry.getKey();
Set<String> set = mapEntry.getValue();
for (String text : set) {
// ...
}
}
}
Nesting sets inside maps inside maps makes the code hard to read though, you might want to use specialized objects instead.
As others have said, in most cases HashMap is preferrable compared to an Hashtable.

Hashmap contains key value

I want to get containsKey value in hashmap:
HashMap hm = new HashMap();
for (Contact ru : registered_users) {
hm.put(ru.getPhone(), ru.getId());
}
if(hm.containsKey(c.getPhone())) {
registered_phone_contacts.add(new Contact("", c.getName());
^^
// Here I need to get value.
}
How can I do that?
You can get it like that:
private String getKey(Integer value){
for(String key : yourHashMap.keySet()){
if(yourHashMap.get(key).equals(value)){
return key; //return the first found
}
}
return null;
}
Or with stream api in java8 :
private Optional<String> getKey(Integer value){
return yourHashMap.entrySet().stream().filter(e -> e.getValue().equals(value)).map(e -> e.getKey()).findFirst();
}
It will works only if there are unique values for your keys...
Update:
There is BiMap in Guava - check out here
You can either retrieve the value from the map in addition to the containsKey :
HashMap hm = new HashMap();
for (Contact ru : registered_users) {
hm.put(ru.getPhone(), ru.getId());
}
if(hm.containsKey(c.getPhone())) {
registered_phone_contacts.add(new Contact(hm.get(c.getPhone()), c.getName());
^^
// value = hm.get(c.getPhone())
}
Or you can retrieved the value first and change the if to test the value instead of contains key :
<TypeOfId> id = hm.get(c.getPhone());
if(id != null) {
registered_phone_contacts.add(new Contact(id, c.getName());
... ^^
}
Hope that helps,
Regards
I assume phone numbers are guaranteed to be unique here, otherwise getting the associated ID for one doesn't makes sense. If so the simplest solution is probably just to build another hashmap with the reverse mapping using: reverseMap.put(ru.getPhone(), ru.getId()).
Then you can just do revserseMap.get(c.getPhone());.
From your example I don't see any need for the forward mapping once you have this reverse one, so you may just be able to delete it.
Just java 8.
Map<Long, String> hm = new HashMap<>();
final Contact c = ...;
Optional<Long> idOpt = hm.entrieSet().stream()
.filter((e) -> e.getValue().equals(c.getPhone())
.map((e2) -> e2.getKey())
.findAny();
idOpt.ifPresent(id -> System.out.println(id));
long id = idOpt.orElse(-1L);

What is the best way to iterate two hashmap in same loop in java?

What's the best way to iterate over the below two maps together? I want to compare two maps values which are strings and have to get the keys and values.
HashMap<String, String> map1;
HashMap<String, String> map2;
There really isn't a better option than
for (Map.Entry<String, String> entry1 : map1.entrySet() {
String key = entry1.getKey();
String value1 = entry1.getValue();
String value2 = map2.get(key);
// do whatever with value1 and value2
}
Depending on what exactly you're trying to do, there are several reasonable options:
Just compare the contents of two maps
Guava provides a Maps.difference() utility that gives you a MapDifference instance letting you inspect exactly what is the same or different between two maps.
Iterate over their entries simultaneously
If you just want to iterate over the entries in two maps simultaneously, it's no different than iterating over any other Collection. This question goes into more detail, but a basic solution would look like this:
Preconditions.checkState(map1.size() == map2.size());
Iterator<Entry<String, String>> iter1 = map1.entrySet().iterator();
Iterator<Entry<String, String>> iter2 = map2.entrySet().iterator();
while(iter1.hasNext() || iter2.hasNext()) {
Entry<String, String> e1 = iter1.next();
Entry<String, String> e2 = iter2.next();
...
}
Note there is no guarantee these entries will be in the same order (and therefore e1.getKey().equals(e2.getKey()) may well be false).
Iterate over their keys to pair up their values
If you need the keys to line up, iterate over the union of both maps' keys:
for(String key : Sets.union(map1.keySet(), map2.keySet()) {
// these could be null, if the maps don't share the same keys
String value1 = map1.get(key);
String value2 = map2.get(key);
...
}
My case if maps are the same sizes
IntStream.range(0, map1.size()).forEach(i -> map1.get(i).equals(map2.get(i));
You can do something like:
for (String key : map1.keySet()) {
if (map2.containsKey(key)) {
// do whatever
} else {
// map2 doesn't have entry with map1 key
}
}

Updating a map in java

I have the following maps :
Map <String,String> m; // contains part details
Map <String,String> n; // contains part details
Map <String,String> o; // the new map that contains both m and n.
I want copy the values from m into o first.
I then want to loop though n and compare keys against o. If key from n, does not exist in o then put key/value it to o.
I tried the below, but the the the second step is not working (values are not copying)
for (Map.Entry<String, String> entry : m.entrySet())
{
String key = entry.getKey();
String value =entry.getValue();
o.put(key, value);
}
for (Map.Entry<String, String> entry : n.entrySet())
{
String key = entry.getKey();
String value =entry.getValue();
for (Map.Entry<String, String> entry1 : o.entrySet())
{
String key1 = entry.getKey();
if(key1 != key)
{
o.put(key,value);
}
}
}
Consider using Map#containsKey(). You can also iterate over a keyset, not over the entryset.
for (String key: n.keySet())
{
if (!o.containsKey(key))
o.put(key,n.get(key));
}
This should work.
I think the problem was you were using direct comparing of Strings, which is not sufficient in your case (almost never), use String#compareTo() method instead.
Why you don't use ready methods? You do not have to write all manually ;).
1) Method putAll() copies all values from one map to the second.
http://docs.oracle.com/javase/7/docs/api/java/util/Map.html#putAll(java.util.Map)
2) Method containsKey() and only one loop.
You don't have to loop through o.
Just use o.containsKey() method
In second inner for loop "String key1 = entry.getKey();" it should be "String key1 = entry1.getKey();"
mistaken between entry and entry1
o.putAll(m); // put all m into o
n.keySet().removeAll(o.keySet()); // Remove all duplicates from n
o.putAll(n); // Now add all filtered n to o

Iterating over and deleting from Hashtable in Java

I have a Hashtable in Java and want to iterate over all the values in the table and delete a particular key-value pair while iterating.
How may this be done?
You need to use an explicit java.util.Iterator to iterate over the Map's entry set rather than being able to use the enhanced For-loop syntax available in Java 6. The following example iterates over a Map of Integer, String pairs, removing any entry whose Integer key is null or equals 0.
Map<Integer, String> map = ...
Iterator<Map.Entry<Integer, String>> it = map.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<Integer, String> entry = it.next();
// Remove entry if key is null or equals 0.
if (entry.getKey() == null || entry.getKey() == 0) {
it.remove();
}
}
You can use Enumeration:
Hashtable<Integer, String> table = ...
Enumeration<Integer> enumKey = table.keys();
while(enumKey.hasMoreElements()) {
Integer key = enumKey.nextElement();
String val = table.get(key);
if(key==0 && val.equals("0"))
table.remove(key);
}
You can use a temporary deletion list:
List<String> keyList = new ArrayList<String>;
for(Map.Entry<String,String> entry : hashTable){
if(entry.getValue().equals("delete")) // replace with your own check
keyList.add(entry.getKey());
}
for(String key : keyList){
hashTable.remove(key);
}
You can find more information about Hashtable methods in the Java API
So you know the key, value pair that you want to delete in advance? It's just much clearer to do this, then:
table.delete(key);
for (K key: table.keySet()) {
// do whatever you need to do with the rest of the keys
}

Categories