Reputation: 29
HashMap<Double, Date> hm1 = new HashMap<Double, Date>();
HashMap<Double, Date> hm2 = new HashMap<Double, Date>();
hm1.put(11, Wed Feb 23 12:56:24 IST 2022);
hm1.put(12, Wed Feb 23 12:56:48 IST 2022);
hm1.put(13, Wed Feb 23 12:56:45 IST 2022);
hm1.put(14, Wed Feb 23 12:56:51 IST 2022);
hm1.put(15, Wed Feb 23 12:56:50 IST 2022);
hm2.put(11, Wed Feb 23 12:56:24 IST 2022);
hm2.put(12, Wed Feb 23 12:56:48 IST 2022);
hm2.put(13, Wed Feb 23 12:56:45 IST 2022);
hm2.put(17, Wed Feb 23 12:56:37 IST 2022);
hm2.put(18, Wed Feb 23 12:56:28 IST 2022);
Need to compare these two hashmaps and get output as hashmap which contains the filtered entries from hm2 i.e remove duplicates after comparing with hm1
output should be
hm2 = {17=Wed Feb 23 12:56:37 IST 2022,
18=Wed Feb 23 12:56:28 IST 2022}
Upvotes: 0
Views: 1610
Reputation: 28978
If my understanding is correct you need to remove from the second map all entries that are contained in the first map. I.e. if both a key and its value are the same).
Side note: class Date
is obsolete and not encouraged to be used. With Java 8 a new IPA that resides in the package java.time
was introduced for such purposes. So I replaced Date
with LocalDateTime
. If for some reason you can't make this change then simply substitute LocalDateTime
with Date
.
The first step is to make a defensive copy of the second map. From your definition of the problem the second map itself has to be mutated, so if you don't need to preserve it intact you omit this step, but for future readers, it's worth being included in the code.
To address the problem fluently instead of nested conditions with containsKey()
checks you can make use of Java 8 enhancements. The flavor of the remove()
that takes a key and value is already mentioned in another answer so I'll sow the alternative approach with the compute() method which was also added into the JDK with Java 8.
Method compute()
takes two arguments: a key and remappingFunction which is a BiFunction that excepts as its arguments the given key and existing value associated with that key (it'll be null
if the key is absent). If remapping function returns null
entry will be removed (in case if it was present).
In the code below iteration happens over the keys in the first map (denoted with a parameter vocub
). Method compute()
is being applied to the result
map, this lambda expression
(k, v) -> !Objects.equals(v, vocab.get(k)) ? v : null
has the following meaning:
k
- the given key;v
- value from result
map associated with that key;Objects.equals(v, vocab.get(k))
does a null-friendly comparison of existing value (which could be null
) and a value from the first map.If both values are equal it remaping function yields null
, i.e entry will be removed.
public static Map<Double, LocalDateTime> removeDuplicates(Map<Double, LocalDateTime> vocab,
Map<Double, LocalDateTime> target) {
Map<Double, LocalDateTime> result = new HashMap<>(target);
for (Double key: vocab.keySet()) {
result.compute(key, (k, v) -> !Objects.equals(v, vocab.get(k)) ? v : null);
}
return result;
}
If you are comfortable with Stream IPA it could be done by iterating over the entry set of the second map and comparing values in both maps.
public static Map<Double, LocalDateTime> removeDuplicates(Map<Double, LocalDateTime> vocab,
Map<Double, LocalDateTime> target) {
return target.entrySet().stream()
.filter(entry -> !Objects.equals(entry.getValue(), vocab.get(entry.getKey())))
.collect(Collectors.toMap(Map.Entry::getKey,
Map.Entry::getValue));
}
main()
public static void main(String[] args) {
Map<Double, LocalDateTime> map1 =
Map.of(1., LocalDateTime.now().minusDays(3),
2., LocalDateTime.now().minusMonths(1),
3., LocalDateTime.now().minusDays(5)
8., LocalDateTime.now().minusHours(1)); // this key isn't present in the map2
Map<Double, LocalDateTime> map2 =
Map.of(1., LocalDateTime.now().minusDays(3),
2., LocalDateTime.now().minusMonths(1),
3., LocalDateTime.now().minusDays(5),
9., LocalDateTime.now());
System.out.println(removeDuplicates(map1, map2));
}
Output (both versions)
{9.0=2022-02-23T17:56:27.784812600}
Upvotes: 1
Reputation: 16498
Use the remove method which accepts two params (key and value).
Removes the entry for the specified key only if it is currently mapped to the specified value.
So in your case:
hm1.forEach((k,v) -> hm2.remove(k,v));
Upvotes: 2
Reputation: 86
If key and value must be the same in order to qualify as a duplicate it would be something like:
Map<Integer, String> hm1 = new HashMap<Integer, String>();
Map<Integer, String> hm2 = new HashMap<Integer, String>();
hm1.put(11, "Wed Feb 23 12:56:24 IST 2022");
hm1.put(12, "Wed Feb 23 12:56:48 IST 2022");
hm1.put(13, "Wed Feb 23 12:56:45 IST 2022");
hm1.put(14, "Wed Feb 23 12:56:51 IST 2022");
hm1.put(15, "Wed Feb 23 12:56:50 IST 2022");
hm2.put(11, "Wed Feb 23 12:56:24 IST 2022");
hm2.put(12, "Wed Feb 23 12:56:48 IST 2022");
hm2.put(13, "Wed Feb 23 12:56:45 IST 2022");
hm2.put(17, "Wed Feb 23 12:56:37 IST 2022");
hm2.put(18, "Wed Feb 23 12:56:28 IST 2022");
//removing duplicates
for (Integer key : hm1.keySet()) {
if (hm2.containsKey(key)) {
if (hm1.get(key).equals(hm2.get(key))) {
hm2.remove(key);
}
}
}
// show content of hm2
System.out.println(hm2);
}
If only the key is relevant to qualify as a duplicate use
for (Integer key : hm1.keySet()) {
hm2.remove(key);
}
instead of
for (Integer key : hm1.keySet()) {
if (hm2.containsKey(key)) {
if (hm1.get(key).equals(hm2.get(key))) {
hm2.remove(key);
}
}
}
Upvotes: 1