I have a list with HashMap<Integer, Point3d> format like in the following way.
{
{key1,(x1,y1,z1)},
{key2,(x2,y2,z2)},
{key3,(x1,y3,z3)},
{key4,(x1,y4,z4)},
{key5,(x5,y5,z5)},
..
}
First I want to seperate first elements from all the points like {x1,x2,x1,x1,x5} and then remove duplicates like {x1,x2,x5} finally length of the result means {x1,x2,x5}.size()
In the same way I want to implement for 2nd and 3rd elements of the Points.
I tried allot but I didn't find anyway.because we can't able to retrieve values from HashMap based on index. we can able to retrieve values based on Key value But I don't know the Keyvalues hashMap.
I tried in the following way.
public int xSideLength(HashMap<Integer, Point3d> coOrdinates) {
int length=0;
Set<Integer> keyValues=coOrdinates.keySet();
Integer[] array=(Integer[]) keyValues.toArray();
for (int index = 0; index < array.length; index++) {
//logical code
}
return length;
}
Can anyone suggest me.
What do you think of the following:
Set<Integer> values = new HashSet<Integer>();
for(Point3d point : coordinates.values()) {
values.add(point.x());
}
return values.size();
You can get elements from the map using the key like this:
Set<Integer> keyValues = coOrdinates.keySet();
for (Integer key : keyValues) {
Point3d point = coOrdinates.get(key);
// Your logical code goes here.
}
You can follow the following steps,
Put the values of the HashMap into a Set with your custom Comparator.
Implement your compare method.
Return the set size.
The snippet looks like below,
public int xSideLength(HashMap<Integer, Point3d> coOrdinates) {
int length=0;
Set<Point3d> values = new TreeSet<Point>(new Comparator<Point3d>() {
#Override
public int compare(Point3d e1, Point3d e2) {
return e1.getX().compareTo(e2.getX());
}
});
values.addAll(coOrdinates.values());
return values.size();
}
public static void zz() {
Map<String,Point3d> m = new HashMap<String,Point3d>();
m.put("k1", new Point3d(1.0, 1.0, 4.0));
m.put("k2", new Point3d(2.0, 2.0, 2.0));
m.put("k3", new Point3d(1.0, 3.0, 2.0));
m.put("k4", new Point3d(1.0, 3.0, 4.0));
m.put("k5", new Point3d(5.0, 3.0, 2.0));
Set xvals = new HashSet();
Set yvals = new HashSet();
Set zvals = new HashSet();
double[] coords = new double[3];
for (Point3d p : m.values()) {
p.get(coords);
xvals.add(coords[0]);
yvals.add(coords[1]);
zvals.add(coords[2]);
}
System.out.println("# unique x: " + xvals.size() + ": " + xvals);
System.out.println("# unique y: " + yvals.size() + ": " + yvals);
System.out.println("# unique z: " + zvals.size() + ": " + zvals);
}
for (Map.Entry<Integer, Point3d> entry : coOrdinates.entrySet()) {
Point3d point = entry.getValue());
}
Related
There is a 2d array with contains set and I want to put it on a map as key. Please, someone, suggest how to do it correctly. Expected and actual outputs are attached below.
public class trysome
{
static int[][] points = {{1,2}, {1,1},{5,7}};
public static void some()
{
HashMap<int[], Integer> map= new HashMap<int[], Integer>();
for(int i =0;i<points.length;i++)
{
map.put(points[i], 1);
}
for(Entry<int[], Integer> entry : map.entrySet())
{
System.out.println(entry.getKey() + " "+entry.getValue());
}
}
public static void main(String[] args)
{
trysome.some();
}
}
Actual Output:
[I#16b4a017 1
[I#8807e25 1
[I#2a3046da 1
Expected Output:
{1,2} 1
{1,1} 1
{5,7} 1
The reason for the output that you are observing is explained in What's the simplest way to print a Java array?. The bottom line is: The output [I#16b4a017 is basically the "memory location" of the array, and just not the contents of the array.
The reason why I'm not closing this as a duplicate is that the output here is just an irrelevant symptom of a much greater flaw: Your approach is conceptually wrong.
You cannot use an int[] array as the key in a hash-based datastructure!
One might argue that it would work if one relied on the identity of the arrays. But that's rarely the case.
The reason for that is that the equals and hashCode methods are not implemented on arrays in the way that would be necessary for this to work. Omitting some technical details that can be read elsewhere.
If your code is supposed to handle 2D points in a plane, then you should use a proper class to represent these points. This class could then include proper implementations of hashCode, equals and toString.
Fortunately, there already is such a class in the Java standard API, namely, java.awt.Point.
The following shows why your original implementation would not work as expected, in the usingArraysAsKeys method, and how it could be implemented properly in the usingPointsAsKeys method:
import java.awt.Point;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
public class PointsAsKeys
{
public static void main(String[] args)
{
usingArraysAsKeys();
usingPointsAsKeys();
}
public static void usingPointsAsKeys()
{
Point points[] =
{
new Point(1, 2),
new Point(1, 1),
new Point(5, 7)
};
Map<Point, Integer> map = new HashMap<Point, Integer>();
for (int i = 0; i < points.length; i++)
{
map.put(points[i], 1);
}
for (Entry<Point, Integer> entry : map.entrySet())
{
Point p = entry.getKey();
String s = "{" + p.x + ", " + p.y + "}";
System.out.println(s + " " + entry.getValue());
}
//=====================================================================
// Important: This shows that it WILL work as expected!
Point somePoint = new Point(1, 2);
Integer value = map.get(somePoint);
System.out.println("Value for " + somePoint + " is " + value);
}
public static void usingArraysAsKeys()
{
int[][] points =
{
{ 1, 2 },
{ 1, 1 },
{ 5, 7 }
};
HashMap<int[], Integer> map = new HashMap<int[], Integer>();
for (int i = 0; i < points.length; i++)
{
map.put(points[i], 1);
}
for (Entry<int[], Integer> entry : map.entrySet())
{
// This would print the arrays as "[I#139a55"
//System.out.println(entry.getKey() + " " + entry.getValue());
// This will print the arrays as [1, 2]:
System.out.println(
Arrays.toString(entry.getKey()) + " " + entry.getValue());
}
//=====================================================================
// Important: This shows that it will NOT work as expected!
int somePoint[] = { 1, 2 };
Integer value = map.get(somePoint);
System.out.println(
"Value for " + Arrays.toString(somePoint) + " is " + value);
}
}
Another advantage of using the Point class is that it already has several convenient methods - most importantly, a Point2D#distance method that allows you to compute the distance of a point to another one:
// Computes the distance of the point to the point at (0,0) (i.e. the origin)
double distanceToOrigin = point.distance(new Point(0,0));
(By the way: If the map is supposed to store distances, then its value type should probably be Double and not Integer)
Try this:
System.out.println(Arrays.toString(entry.getKey()) + " "+entry.getValue());
Output (for example):
[1, 2] 1
Or if you want to exact as Expected Output:
System.out.println(String.format("{%d,%d}", entry.getKey()[0], entry.getKey()[1]) +
" " + entry.getValue());
This method can help you:
private static String intArrayToString(int[] inputArray) {
StringBuilder output = new StringBuilder().append('{');
for (int i = 0; i < inputArray.length - 1; i++) {
output.append(inputArray[i]);
output.append(',');
}
output.append(inputArray[inputArray.length - 1]);
return output.append('}').toString();
}
}
You can use it like this:
System.out.println(intArrayToString(entry.getKey()) + " " + entry.getValue());
Benefits of this solution are that you can customize it as you wish.
For a special slope for linear distances, I need to check wether a new point with given lat/lon has a distance greater than 10 km with respect to all other points, which are stored in a map. I'd like to avoid, that all points inside the map are compared sequentially.
I tried the following code:
private static Map<Long,String> getTop10DSEGs() throws IOException {
Map<Long,String> top10Dsegs = new HashMap<>();
List<String> allDsegs = loadDsegRanking(rFiles);
//the list allDsegs is a csv with the following structure
//dsegID, Latitide, Longitude
//1167317891449551556,51.435550689697266,6.695819854736328
double LatFromList, LonFromList;
double LatFromMap, LonFromMap;
String[] listArray;
String[] mapArray;
Long firstDseg = Long.parseLong(allDsegs.get(0).substring(0, 19));
top10Dsegs.put(firstDseg, allDsegs.get(0).substring(20));
//Iterating through all dsegs
for(String line : allDsegs){
Long nextID = null;
String nextCoordinates = "0.0000,0.0000";
listArray = line.split(",");
LatFromList = Double.valueOf(listArray[1]);
LonFromList = Double.valueOf(listArray[2]);
//checking all coordinates of maped dsegs
for(Map.Entry<Long, String> entry : top10Dsegs.entrySet()){
List<Double> distanceList = new ArrayList<>();
mapArray = entry.getValue().split(",");
LatFromMap = Double.valueOf(mapArray[0]);
LonFromMap = Double.valueOf(mapArray[1]);
//calculating the distance between the next city from the list and the other dsegs from the map
//result of dist is a double and it's metric is Km.
Double dist = Implements.DistanceCalculator.distance(LatFromMap, LonFromMap, LatFromList, LonFromList, "K");
distanceList.add(dist);
for(Double value : distanceList){
if (dist>10){
nextID = Long.parseLong(listArray[0]);
nextCoordinates = listArray[1] + "," + listArray[2];
}
}
}
if(nextID != null && top10Dsegs.size() < 10){
top10Dsegs.put(nextID, nextStartCoordinates);
}
return top10Dsegs;
}
To avoid calculating and comparing distance between all the already stored points and the new one you may use some kind of grid (or matrix) implemented by (Multi)Map or array. Each cell of the grid may have size of sqrt(10km) and contains all the points with relevant coords. It is easy to calculate coordinates of suitable cell for the point by dividing it's coords by sqrt(10).
So when adding every next point it is possible to check distance to only points in 9 cells (own + around). I suppose it will be much less than all points on the map.
Have a look at anyMatch in the Java 8 Stream API
boolean exists = allDsegs.stream().anyMatch(x -> x.equals(firstDseg /* or whetever you compare */));
Okay guys.
Now I solved it by using the Stream-Api and there allMatch()-Method. The problem was, that I've created a Map to save new elements and furthermore the test check = allDsegs.stream().anyMatch(x->dist>10); was the wrong.
The solution is to use a list(top10List) for the new elements and the test need to check if there are elements in the top10List, which are smaller than 10 km.
Here is the code, which (unfortunately) is not beautiful. Im just a beginner since 7 months:
private static List<Top10Dsegs> getTop10DSEGs() throws IOException {
List<File>rFiles = getRFiles();
List<String> allDsegs = loadDsegRanking(rFiles);
List<Top10Dsegs> top10List = new ArrayList<>();
double startLat_allDsegs, startLon_allDsegs;
double startLat_top10List, startLon_top10List;
String[] listArray;
//declaring the starting dseg and its coordinates
String startEntry = allDsegs.get(0);
Top10Dsegs firstEntry = new Top10Dsegs(startEntry);
top10List.add(firstEntry);
System.out.println("Iteration starts here!\n---------------------");
//begin to iterate over all entries (just ranked)
for(String line : allDsegs){
boolean check=true;
Top10Dsegs nextEntry=null;
//structure from allDsegs:
//DSEG,startLat,startLon
//1231231231231231231, 54.123, 8.456
listArray = line.split(",");
startLat_allDsegs = Double.valueOf(listArray[1]);
startLon_allDsegs = Double.valueOf(listArray[2]);
//start to check if line-entry of allDsegs has a distance > 10 km compared to given Dsegs
for(Top10Dsegs entry : top10List){
startLat_top10List = entry.getStartLat();
startLon_top10List = entry.getStartLon();
//the DistanceCalculator calculates the distance between the dseg from allDsegs and the other dseg from top10Dsegs
DistanceCalculator distanceCalculator = new DistanceCalculator();
Double dist = distanceCalculator.distance(startLat_top10List, startLon_top10List, startLat_allDsegs, startLon_allDsegs, "K");
System.out.println("Checked Dseg: " + listArray[0]);
System.out.println("Distance between checked Dseg and " + entry.getSegmentID() + " = " + dist);
//check if there is a dseg from allDsegs distance > 10 km compared to ALL OTHER dsegs
if(top10List.stream().allMatch(x->dist<10)==true){
check = false;
}
System.out.println("Are all distances > 10 ? \t" + check);
}
if(check==true && top10List.size()<10){
nextEntry = new Top10Dsegs(listArray[0]+","+listArray[1]+","+listArray[2]);
top10List.add(nextEntry);
}
System.out.println("Progress: \n"+top10List.size()+" entries inside top 10 list. \n<---------------->\nNext Iteration:");
}
return top10List;
}
I have the following code (with some sample data), and wished to check whether there is any better or performant way to compare each element of the list of map to the subsequent one:
import java.util.*;
public class CompareElements {
private static List<Map<String, String>> sample = new ArrayList<>(0);
private static int MIN = 0;
private static int MAX = 10;
static {
populateListOfMaps();
}
/*
* This is the main part of the question, rest is just to generate test data..
*/
public static void main(String[] args){
// Can we simplify this part using lambda's or any library?
for (int i = 0; i < sample.size() -1; i++) {
for (int j = i+1; j < sample.size(); j++) {
Map<String, String> referenceMap = sample.get(i);
Map<String, String> candideMap = sample.get(j);
if(referenceMap.get("key").equalsIgnoreCase(candideMap.get("key"))){
System.out.println("Equal : " + i + " || " + referenceMap.get("key") + " and "+ j + " || " + candideMap.get("key") + " are pairs");
} else {
System.out.println("Not equal : " + i + " || " + referenceMap.get("key") + " and "+ j + " || " + candideMap.get("key") + " are pairs");
}
}
}
}
private static void populateListOfMaps(){
if(sample.size() <= 10){
Map<String, String> someMap = new HashMap<>(0);
someMap.put("key", "value" + randInt(MIN, MAX));
sample.add(someMap);
populateListOfMaps();
}
}
public static int randInt(int min, int max) {
Random rand = new Random();
int randomNum = rand.nextInt((max - min) + 1) + min;
return randomNum;
}
}
My requirement is to compare each element of the list of maps and then check for equality to remove duplicate, this is a simpler part, but each map in my real time application has 2 keys-values (but both are String.. no custom POJO object).
The above code works but I wish to make this more concise and performant code.
Can we use lambdas or streams?
As you are getting data from MongoDB, I assume you have no control over the schema, so using a POJO isn't a simple option. (it can be done with generated code, but you probably don't want to go there)
What you can do is using groupingBy to change this O(n^2) loops into O(n)
public static void main(String... args) {
List<Map<String, String>> sample = populateListOfMaps();
sample.stream()
.collect(Collectors.groupingBy(m -> m.get("key")))
.forEach((key, list) -> System.out.println(key + " : " + list));
}
private static List<Map<String, String>> populateListOfMaps() {
Random rand = new Random();
return IntStream.range(0, 10)
.mapToObj(i -> {
Map<String, String> someMap = new HashMap<>(2);
someMap.put("key", "value-" + rand.nextInt(10));
return someMap;
})
.collect(Collectors.toList());
}
This will print all the entries which have the same "key" value with O(n) time complexity. e.g.
value-9 : [{key=value-9}]
value-8 : [{key=value-8}, {key=value-8}, {key=value-8}]
value-5 : [{key=value-5}]
value-7 : [{key=value-7}, {key=value-7}]
value-1 : [{key=value-1}]
value-0 : [{key=value-0}]
value-2 : [{key=value-2}]
I'm not realy sure what your exact requirements are so to tackle your question one part at a time:
check whether there is any better or performant way to compare each element of the list of map to the subsequent one:
How about using keySets?
Set<String> s1 = new HashSet< String >(referenceMap.values());
Set<String> s2 = new HashSet< String >(candideMap.values());
// Get intersection of values
s1.retainAll(s2);
// You can also get corresponding keys for each value later
This should reduce your complexity from O(n^2) to O(n)
each map in my real time application has 2 keys-values (but both are String.. no custom POJO object).
Not sure what you mean by real-time. Are the maps changing in real time? Neither your solution nor mine would be thread safe.
Do you mean 2 keys-values for each entry? If you mean 2 values for each key, you would probably override the hashcode(), equals() and your code should work.
Let me know if I misunderstood your question
I have read a little about ConcurrentModificationException in stackflow and my actual update appears not to be the issue, it could be a problem in my design or I need a technique I haven't learnt yet.
Example Situation:
My iterator is running along position markers.
Then an action can be performed to shift the markers over (e.g. Inserting into string).
All Markers greater than the current position must also be shifted to preserve correctness.
Task:
How do I update the remaining markers without the iterator exploding?
Can I refresh the iterator, or break and start the loop again?
The following code is abstracted from my work.
public void innerLoop(Boolean b) {
//An Example of what I'm working with
HashMap<String, HashSet<Integer>> map = new HashMap<String, HashSet<Integer>>() {
{
put("Nonce",
new HashSet<Integer>() {
{
add(1);
add(2);
add(3);
add(4);
add(5);
}
});
}
};
//for each key
for (String key: map.keySet()) {
HashSet<Integer> positions = map.get(key);
//for each integer
for (Iterator<Integer> it = positions.iterator(); it.hasNext();) {
Integer position = it.next();
System.out.println("position =" + position);
//(out of scope) decision requiring elements from the outter loops
if (new Random().nextBoolean()&&b) {
//shift position by +4 (or whatever)
//and every other (int >= position)
System.out.println("Shift " + position + " by 4");
Integer shift = 4;
update(position,
shift,
positions);
it.remove();
}
}
}
}
public void update(Integer current,
Integer diff,
Set<Integer> set) {
if (set != null) {
HashSet<Integer> temp = new HashSet<Integer>();
for (Integer old: set) {
if (old >= current) {
temp.add(old);
System.out.println(old + "Added to temp");
}
}
for (Integer old: temp) {
set.remove(old);
System.out.println(old + "removed");
set.add(old + diff);
System.out.println((old + diff) + "Added");
}
}
}
Edited with Garrett Hall Solution
public void nestedloops() {
HashMap<String, HashSet<Integer>> map = new HashMap<String, HashSet<Integer>>() {
{
put("Hello",
new HashSet<Integer>() {
{
add(5);
add(2);
add(3);
add(4);
add(1);
add(6);
}
});
}
};
//for each key
for (String key: map.keySet()) {
ArrayList<Integer> positions = new ArrayList<Integer>(map.get(key));
//for each integer
for (int i = 0; i < positions.size(); i++) {
Integer position = positions.get(i);
System.out.println("[" + i + "] =" + position);
//out of scope decision
if (new Random().nextBoolean()) {
//shift position by +4
//and every other (int >= position)
System.out.println("Shift after " + position + " by 4");
Integer shift = 4;
//Update the array
for (int j = 0; j < positions.size(); j++) {
Integer checkPosition = positions.get(j);
if (checkPosition > position) {
System.out.println(checkPosition + "increased by 4");
positions.set(j,
checkPosition + shift);
}
}
}
}
//Add updated Array
map.put(key,
new HashSet<Integer>(positions));
}
}
You best bet is indexing the HashSet by putting it into a list. Then you can use indices to refer to elements rather than an Iterator. So long as you are not removing or adding (only updating) elements, then your indices will be correct. Otherwise you will have to account for that. Example:
ArrayList<Integer> positions = new ArrayList<Integer>(map.get(key));
for (int i = 0; i < positions.size(); i ++) {
// updating list
for (int j = i; i < positions.size(); j ++) {
positions.set(j, positions.get(i) + diff);
}
}
I would copy the original set to a list so that you don't need to worry about the current iteration code. Then update a secondary list (not being iterated).
Reasons:
You can't iterate and modify your original collection at once (there is no way around the ConcurrentModificationExceptions)
Nice one liner to shift items in a list.
Collections.rotate(list.subList(j, k+1), -1);
Guava will be able to handle the "find first index that satisfies that predicate and transform the list" which a bunch of utility methods.
In java, I want to compare two maps, like below, do we have existing API to do this ?
Thanks
Map<String, String> beforeMap ;
beforeMap.put("a", "1");
beforeMap.put("b", "2");
beforeMap.put("c", "3");
Map<String, String> afterMap ;
afterMap.put("a", "1");
afterMap.put("c", "333");
//--- it should give me:
b is missing, c value changed from '3' to '333'
I'd use removeAll() functionality of Set to to do set differences of keys to find additions and deletions. Actual changes can be detected by doing a set difference using the entry set as HashMap.Entry implements equals() using both key and value.
Set<String> removedKeys = new HashSet<String>(beforeMap.keySet());
removedKeys.removeAll(afterMap.keySet());
Set<String> addedKeys = new HashSet<String>(afterMap.keySet());
addedKeys.removeAll(beforeMap.keySet());
Set<Entry<String, String>> changedEntries = new HashSet<Entry<String, String>>(
afterMap.entrySet());
changedEntries.removeAll(beforeMap.entrySet());
System.out.println("added " + addedKeys);
System.out.println("removed " + removedKeys);
System.out.println("changed " + changedEntries);
Output
added []
removed [b]
changed [c=333]
The Guava Maps class has some methods for calulating the differences between a pair of maps. However, these methods give you a data structure representing the differences not a pretty-printed string.
There isn't any out of the box component to help with that. You'll probably have to code it unfortunately. The good news is the logic is pretty easy.
Depending upon your particular needs, you might also consider using other applications designed to do this work, like diff. You could write the two maps to two different files, and diff the files.
String output = new String();
for (String key:beforeMap.getKeys()){
String beforeValue = beforeMap.getValue(key);
String afterValue = afterMap.getValue(key);
//nullsafe
if(beforeValue.equals(afterValue){}
else if (afterValue == null){
output = output + key + " is missing, ";
continue;
}else {
output = output + key + " has changed from " + beforeValue + " to " + afterValue + " , ";
}
afterMap.remove(key);
}
for (String key:afterMap.getKeys()){
output = output + key + " was added with value " + afterMap.getValue(key) + ", ";
}
if(output == null){
output = "Same map";
}
output = output.substring(0,output.length-2);
System.out.println(output);
You could use a custom object that contains the key and the value (actually Map does this internally, hidden from the user, so we can't use that)
Put these tuples into a Set
To compare two sets, convert them both to arrays, sort the arrays and walk both arrays from begin to end in parallel, stepping down the first array if it's key is smaller than the key in the second array, and vise versa.
class Tuple implements Comparable<Tuple>
{
public String key;
public String value;
public Tuple(String key, String value)
{
this.key = key;
this.value = value;
}
#Override
public int compareTo(Tuple o)
{
return key.compareTo(o.key);
}
}
public static void main(String[] args)
{
// TreeSet is already sorted. If you use HashSet, use Arrays.sort()
Set<Tuple> beforeSet = new TreeSet<>();
beforeSet.add(new Tuple("a", "1"));
beforeSet.add(new Tuple("b", "2"));
beforeSet.add(new Tuple("c", "4"));
Set<Tuple> afterSet = new TreeSet<>();
afterSet.add(new Tuple("a", "1"));
afterSet.add(new Tuple("c", "333"));
afterSet.add(new Tuple("aa", "4"));
Tuple[] beforeArray = beforeSet.toArray(new Tuple[beforeSet.size()]);
Tuple[] afterArray = afterSet.toArray(new Tuple[afterSet.size()]);
int beforePtr = 0;
int afterPtr = 0;
while (beforePtr < beforeArray.length || afterPtr < afterArray.length)
{
int difference = afterPtr >= afterArray.length? -1 : beforePtr >= beforeArray.length? 1 : beforeArray[beforePtr].compareTo(afterArray[afterPtr]);
if (difference == 0)
{
if (!beforeArray[beforePtr].value.equals(afterArray[afterPtr].value))
{
System.out.println(beforeArray[beforePtr].key + " value changed from '" + beforeArray[beforePtr].value + "' to '" + afterArray[afterPtr].value + "'");
}
beforePtr++;
afterPtr++;
}
else if (difference < 0)
{
System.out.println(beforeArray[beforePtr].key + " is missing");
beforePtr++;
}
else
{
System.out.println(afterArray[afterPtr].key + " is added");
afterPtr++;
}
}
}
#user595234 To Compare the two Maps you can add the keys of a map to list and with those 2 lists you can use the methods retainAll() and removeAll() and add them to another common keys list and different keys list. Using the keys of the common list and different list you can iterate through map, using equals you can compare the maps.
public class Demo
{
public static void main(String[] args)
{
Map<String, String> beforeMap = new HashMap<String, String>();
beforeMap.put("a", "1");
beforeMap.put("b", "2");
beforeMap.put("c", "3");
Map<String, String> afterMap = new HashMap<String, String>();
afterMap.put("a", "1");
afterMap.put("c", "333");
System.out.println("Before "+beforeMap);
System.out.println("After "+afterMap);
List<String> beforeList = getAllKeys(beforeMap);
List<String> afterList = getAllKeys(afterMap);
List<String> commonList1 = beforeList;
List<String> commonList2 = afterList;
List<String> diffList1 = getAllKeys(beforeMap);
List<String> diffList2 = getAllKeys(afterMap);
commonList1.retainAll(afterList);
commonList2.retainAll(beforeList);
diffList1.removeAll(commonList1);
diffList2.removeAll(commonList2);
System.out.println("Common List of before map "+commonList1);
System.out.println("Common List of after map "+commonList2);
System.out.println("Diff List of before map "+diffList1);
System.out.println("Diff List of after map "+diffList2);
if(commonList1!=null & commonList2!=null) // athough both the size are same
{
for (int i = 0; i < commonList1.size(); i++)
{
if ((beforeMap.get(commonList1.get(i))).equals(afterMap.get(commonList1.get(i))))
{
System.out.println("Equal: Before- "+ beforeMap.get(commonList1.get(i))+" After- "+afterMap.get(commonList1.get(i)));
}
else
{
System.out.println("Unequal: Before- "+ beforeMap.get(commonList1.get(i))+" After- "+afterMap.get(commonList1.get(i)));
}
}
}
if (CollectionUtils.isNotEmpty(diffList1))
{
for (int i = 0; i < diffList1.size(); i++)
{
System.out.println("Values present only in before map: "+beforeMap.get(diffList1.get(i)));
}
}
if (CollectionUtils.isNotEmpty(diffList2))
{
for (int i = 0; i < diffList2.size(); i++)
{
System.out.println("Values present only in after map: "+afterMap.get(diffList2.get(i)));
}
}
}
/** getAllKeys API adds the keys of the map to a list */
private static List<String> getAllKeys(Map<String, String> map1)
{
List<String> key = new ArrayList<String>();
if (map1 != null)
{
Iterator<String> mapIterator = map1.keySet().iterator();
while (mapIterator.hasNext())
{
key.add(mapIterator.next());
}
}
return key;
}
}
The below code will give you this output:
Before: {b=2, c=3, a=1}
After: {c=333, a=1}
Unequal: Before- 3 After- 333
Equal: Before- 1 After- 1
Values present only in before map: 2