How to compare two HashMap<String, List> with list items as values to check if value in hMap1 is...
up vote
1
down vote
favorite
I have two separate maps with List of items as values. I'm reading data from two separate xml files to populate these maps.
The contents of the maps look like this:
Map<String,List<String>> hMap1 = new HashMap<>();
Map<String,List<String>> hMap2 = new HashMap<>();
hmAP1 key:Bob val[aa,bb,cc,dd,ee]
key:Sam val[ss,tt,uu,vv,ww]
hMap2 key:Dan val[xx,pp,yy,qq,zz]
key:Bob val[cc,dd,hh,kk,mm]
I want to compare the values in hMap1 and hMap2. In this case Bob in hMap1 [cc, dd] has values that are similar to Bob in hMap2 [cc, dd].
How do I add Bob and matching values only to new hMap3. I can't seem to get my head around, please.
Here's how far I've gone with reading the xml files and adding to hashMaps:
public static Map<String,List<String>> checkSimilarValues (File file) throws TransformerException, ParserConfigurationException, SAXException, IOException
{
Map<String, List<String>> hMap = new HashMap<>();
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc1 = dBuilder.parse(file);
// System.out.println(file.getName());
doc1.getDocumentElement().normalize();
NodeList nList = doc1.getElementsByTagName("class");
for (int temp = 0; temp < nList.getLength(); temp++) {
Node nNode = nList.item(temp);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
// list of include methods
NodeList includeMethods = eElement.getElementsByTagName("include");
for (int count = 0; count < includeMethods.getLength(); count++) {
Node node1 = includeMethods.item(count);
if (node1.getNodeType() == node1.ELEMENT_NODE) {
Element methods = (Element) node1;
List<String> current =
hMap.get(eElement.getAttribute("name"));
// List<String> current2 =
map.get(eElement.getAttribute("name"));
if (current == null) {
current = new ArrayList<String>();
hMap.put(eElement.getAttribute("name"), current);
}
if (!(current.contains(methods.getAttribute("name")))) {
current.add(methods.getAttribute("name"));
}
}
}
}
}
return hMap;
}
public static void main (String args) throws ParserConfigurationException, SAXException, IOException, TransformerException
{
File f1 = new File("sample1.xml");
File f2 = new File("sample2.xml");
Map<String, List<String>> hMap1 = new HashMap<>();
Map<String, List<String>> hMap2 = new HashMap<>();
hMap1 = checkSimilarValues(f1);
hMap2 = checkSimilarValues(f2);
for (String key : hMap1.keySet()) {
System.out.println(key);
for (String string : hMap1.get(key)) {
System.out.println(string);
}
}
}
sample1.xml
<classes>
<class name="Bob">
<methods>
<include name="cc" />
<include name="cc" />
<include name="hh" />
<include name="kk" />
<include name="mm" />
</methods>
</class>
<class name="Dan">
<methods>
<include name="xx" />
<include name="pp" />
<include name="yy" />
<include name="qq" />
<include name="zz" />
</methods>
</class>
sample2.xml
<classes>
<class name="Bob">
<methods>
<include name="aa" />
<include name="bb" />
<include name="cc" />
<include name="dd" />
<include name="ee" />
</methods>
</class>
<class name="Sam">
<methods>
<include name="ss" />
<include name="tt" />
<include name="uu" />
<include name="vv" />
<include name="ww" />
</methods>
</class>
java xml hashmap
add a comment |
up vote
1
down vote
favorite
I have two separate maps with List of items as values. I'm reading data from two separate xml files to populate these maps.
The contents of the maps look like this:
Map<String,List<String>> hMap1 = new HashMap<>();
Map<String,List<String>> hMap2 = new HashMap<>();
hmAP1 key:Bob val[aa,bb,cc,dd,ee]
key:Sam val[ss,tt,uu,vv,ww]
hMap2 key:Dan val[xx,pp,yy,qq,zz]
key:Bob val[cc,dd,hh,kk,mm]
I want to compare the values in hMap1 and hMap2. In this case Bob in hMap1 [cc, dd] has values that are similar to Bob in hMap2 [cc, dd].
How do I add Bob and matching values only to new hMap3. I can't seem to get my head around, please.
Here's how far I've gone with reading the xml files and adding to hashMaps:
public static Map<String,List<String>> checkSimilarValues (File file) throws TransformerException, ParserConfigurationException, SAXException, IOException
{
Map<String, List<String>> hMap = new HashMap<>();
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc1 = dBuilder.parse(file);
// System.out.println(file.getName());
doc1.getDocumentElement().normalize();
NodeList nList = doc1.getElementsByTagName("class");
for (int temp = 0; temp < nList.getLength(); temp++) {
Node nNode = nList.item(temp);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
// list of include methods
NodeList includeMethods = eElement.getElementsByTagName("include");
for (int count = 0; count < includeMethods.getLength(); count++) {
Node node1 = includeMethods.item(count);
if (node1.getNodeType() == node1.ELEMENT_NODE) {
Element methods = (Element) node1;
List<String> current =
hMap.get(eElement.getAttribute("name"));
// List<String> current2 =
map.get(eElement.getAttribute("name"));
if (current == null) {
current = new ArrayList<String>();
hMap.put(eElement.getAttribute("name"), current);
}
if (!(current.contains(methods.getAttribute("name")))) {
current.add(methods.getAttribute("name"));
}
}
}
}
}
return hMap;
}
public static void main (String args) throws ParserConfigurationException, SAXException, IOException, TransformerException
{
File f1 = new File("sample1.xml");
File f2 = new File("sample2.xml");
Map<String, List<String>> hMap1 = new HashMap<>();
Map<String, List<String>> hMap2 = new HashMap<>();
hMap1 = checkSimilarValues(f1);
hMap2 = checkSimilarValues(f2);
for (String key : hMap1.keySet()) {
System.out.println(key);
for (String string : hMap1.get(key)) {
System.out.println(string);
}
}
}
sample1.xml
<classes>
<class name="Bob">
<methods>
<include name="cc" />
<include name="cc" />
<include name="hh" />
<include name="kk" />
<include name="mm" />
</methods>
</class>
<class name="Dan">
<methods>
<include name="xx" />
<include name="pp" />
<include name="yy" />
<include name="qq" />
<include name="zz" />
</methods>
</class>
sample2.xml
<classes>
<class name="Bob">
<methods>
<include name="aa" />
<include name="bb" />
<include name="cc" />
<include name="dd" />
<include name="ee" />
</methods>
</class>
<class name="Sam">
<methods>
<include name="ss" />
<include name="tt" />
<include name="uu" />
<include name="vv" />
<include name="ww" />
</methods>
</class>
java xml hashmap
You can first start with a brute force approach.
– Sid
yesterday
Implement a Comparator
– Anastasios Moraitis
yesterday
You can use reverse lookup where instead of class as key, use method as key
– mani deepak
yesterday
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I have two separate maps with List of items as values. I'm reading data from two separate xml files to populate these maps.
The contents of the maps look like this:
Map<String,List<String>> hMap1 = new HashMap<>();
Map<String,List<String>> hMap2 = new HashMap<>();
hmAP1 key:Bob val[aa,bb,cc,dd,ee]
key:Sam val[ss,tt,uu,vv,ww]
hMap2 key:Dan val[xx,pp,yy,qq,zz]
key:Bob val[cc,dd,hh,kk,mm]
I want to compare the values in hMap1 and hMap2. In this case Bob in hMap1 [cc, dd] has values that are similar to Bob in hMap2 [cc, dd].
How do I add Bob and matching values only to new hMap3. I can't seem to get my head around, please.
Here's how far I've gone with reading the xml files and adding to hashMaps:
public static Map<String,List<String>> checkSimilarValues (File file) throws TransformerException, ParserConfigurationException, SAXException, IOException
{
Map<String, List<String>> hMap = new HashMap<>();
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc1 = dBuilder.parse(file);
// System.out.println(file.getName());
doc1.getDocumentElement().normalize();
NodeList nList = doc1.getElementsByTagName("class");
for (int temp = 0; temp < nList.getLength(); temp++) {
Node nNode = nList.item(temp);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
// list of include methods
NodeList includeMethods = eElement.getElementsByTagName("include");
for (int count = 0; count < includeMethods.getLength(); count++) {
Node node1 = includeMethods.item(count);
if (node1.getNodeType() == node1.ELEMENT_NODE) {
Element methods = (Element) node1;
List<String> current =
hMap.get(eElement.getAttribute("name"));
// List<String> current2 =
map.get(eElement.getAttribute("name"));
if (current == null) {
current = new ArrayList<String>();
hMap.put(eElement.getAttribute("name"), current);
}
if (!(current.contains(methods.getAttribute("name")))) {
current.add(methods.getAttribute("name"));
}
}
}
}
}
return hMap;
}
public static void main (String args) throws ParserConfigurationException, SAXException, IOException, TransformerException
{
File f1 = new File("sample1.xml");
File f2 = new File("sample2.xml");
Map<String, List<String>> hMap1 = new HashMap<>();
Map<String, List<String>> hMap2 = new HashMap<>();
hMap1 = checkSimilarValues(f1);
hMap2 = checkSimilarValues(f2);
for (String key : hMap1.keySet()) {
System.out.println(key);
for (String string : hMap1.get(key)) {
System.out.println(string);
}
}
}
sample1.xml
<classes>
<class name="Bob">
<methods>
<include name="cc" />
<include name="cc" />
<include name="hh" />
<include name="kk" />
<include name="mm" />
</methods>
</class>
<class name="Dan">
<methods>
<include name="xx" />
<include name="pp" />
<include name="yy" />
<include name="qq" />
<include name="zz" />
</methods>
</class>
sample2.xml
<classes>
<class name="Bob">
<methods>
<include name="aa" />
<include name="bb" />
<include name="cc" />
<include name="dd" />
<include name="ee" />
</methods>
</class>
<class name="Sam">
<methods>
<include name="ss" />
<include name="tt" />
<include name="uu" />
<include name="vv" />
<include name="ww" />
</methods>
</class>
java xml hashmap
I have two separate maps with List of items as values. I'm reading data from two separate xml files to populate these maps.
The contents of the maps look like this:
Map<String,List<String>> hMap1 = new HashMap<>();
Map<String,List<String>> hMap2 = new HashMap<>();
hmAP1 key:Bob val[aa,bb,cc,dd,ee]
key:Sam val[ss,tt,uu,vv,ww]
hMap2 key:Dan val[xx,pp,yy,qq,zz]
key:Bob val[cc,dd,hh,kk,mm]
I want to compare the values in hMap1 and hMap2. In this case Bob in hMap1 [cc, dd] has values that are similar to Bob in hMap2 [cc, dd].
How do I add Bob and matching values only to new hMap3. I can't seem to get my head around, please.
Here's how far I've gone with reading the xml files and adding to hashMaps:
public static Map<String,List<String>> checkSimilarValues (File file) throws TransformerException, ParserConfigurationException, SAXException, IOException
{
Map<String, List<String>> hMap = new HashMap<>();
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc1 = dBuilder.parse(file);
// System.out.println(file.getName());
doc1.getDocumentElement().normalize();
NodeList nList = doc1.getElementsByTagName("class");
for (int temp = 0; temp < nList.getLength(); temp++) {
Node nNode = nList.item(temp);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
// list of include methods
NodeList includeMethods = eElement.getElementsByTagName("include");
for (int count = 0; count < includeMethods.getLength(); count++) {
Node node1 = includeMethods.item(count);
if (node1.getNodeType() == node1.ELEMENT_NODE) {
Element methods = (Element) node1;
List<String> current =
hMap.get(eElement.getAttribute("name"));
// List<String> current2 =
map.get(eElement.getAttribute("name"));
if (current == null) {
current = new ArrayList<String>();
hMap.put(eElement.getAttribute("name"), current);
}
if (!(current.contains(methods.getAttribute("name")))) {
current.add(methods.getAttribute("name"));
}
}
}
}
}
return hMap;
}
public static void main (String args) throws ParserConfigurationException, SAXException, IOException, TransformerException
{
File f1 = new File("sample1.xml");
File f2 = new File("sample2.xml");
Map<String, List<String>> hMap1 = new HashMap<>();
Map<String, List<String>> hMap2 = new HashMap<>();
hMap1 = checkSimilarValues(f1);
hMap2 = checkSimilarValues(f2);
for (String key : hMap1.keySet()) {
System.out.println(key);
for (String string : hMap1.get(key)) {
System.out.println(string);
}
}
}
sample1.xml
<classes>
<class name="Bob">
<methods>
<include name="cc" />
<include name="cc" />
<include name="hh" />
<include name="kk" />
<include name="mm" />
</methods>
</class>
<class name="Dan">
<methods>
<include name="xx" />
<include name="pp" />
<include name="yy" />
<include name="qq" />
<include name="zz" />
</methods>
</class>
sample2.xml
<classes>
<class name="Bob">
<methods>
<include name="aa" />
<include name="bb" />
<include name="cc" />
<include name="dd" />
<include name="ee" />
</methods>
</class>
<class name="Sam">
<methods>
<include name="ss" />
<include name="tt" />
<include name="uu" />
<include name="vv" />
<include name="ww" />
</methods>
</class>
java xml hashmap
java xml hashmap
edited yesterday
asked yesterday
James Ngondo
142
142
You can first start with a brute force approach.
– Sid
yesterday
Implement a Comparator
– Anastasios Moraitis
yesterday
You can use reverse lookup where instead of class as key, use method as key
– mani deepak
yesterday
add a comment |
You can first start with a brute force approach.
– Sid
yesterday
Implement a Comparator
– Anastasios Moraitis
yesterday
You can use reverse lookup where instead of class as key, use method as key
– mani deepak
yesterday
You can first start with a brute force approach.
– Sid
yesterday
You can first start with a brute force approach.
– Sid
yesterday
Implement a Comparator
– Anastasios Moraitis
yesterday
Implement a Comparator
– Anastasios Moraitis
yesterday
You can use reverse lookup where instead of class as key, use method as key
– mani deepak
yesterday
You can use reverse lookup where instead of class as key, use method as key
– mani deepak
yesterday
add a comment |
3 Answers
3
active
oldest
votes
up vote
1
down vote
It's much easier to do this at the XML level using XSLT (2.0 or higher) rather than doing it at the Java level. For example you can create a document that merges the two inputs supplied using
<xsl:variable name="inputs" select="doc('sample1.xml'), doc('sample2.xml')"/>
<xsl:template name="main">
<classes>
<xsl:for-each-group select="$inputs//class" group-by="@name">
<methods>
<xsl:for-each select="distinct-values(current-group()/methods/include/@name">
<include name="{.}"/>
</xsl:for-each>
</methods>
</xsl:for-each-group>
</classes>
</xsl:template>
This gives you the union of all the "include" elements for each name - I'm not sure if that's quite what you're asking for. It would be easier if you gave a high-level description of the problem you are trying to solve, rather than expressing it in terms of manipulations of Java hash tables.
add a comment |
up vote
0
down vote
You can try this:
Map<String, List<String>> resultMap = new HashMap<>();
for (String k: hMap1.keySet()) {
if (!hMap2.containsKey(k)) continue;
List<String> list = new ArrayList<>(hMap1.get(k));
list.retainAll(hMap2.get(k));
resultMap.put(k, list);
}
Thank you very much for your time and effort in helping out. This works very fine. Thanks.
– James Ngondo
yesterday
add a comment |
up vote
0
down vote
It's very easy in Java 8. You could stream both maps entries, filter entries whose key belongs to both maps and collect these entries to a new map, merging the values by intersecting them. In code:
Map<String, List<String>> hMap3 = Stream.of(hMap1, hMap2)
.flatMap(map -> map.entrySet().stream())
.filter(e -> hMap1.containsKey(e.getKey()) && hMap2.containsKey(e.getKey()))
.collect(Collectors.toMap(
Map.Entry::getKey,
e -> new ArrayList<>(e.getValue()),
(l1, l2) -> { l1.retainAll(l2); return l1; }));
Another possibility would be to iterate over hMap1
keys and if hMap2
contains the current key, put an entry into the new map that maps the key to the intersection of the values:
Map<String, List<String>> hMap3 = new HashMap<>();
hMap1.forEach((k1, v1) -> {
List<String> v2 = hMap2.get(k1);
if (v2 != null) {
List<String> v3 = new ArrayList<>(v1);
v3.retainAll(v2);
hMap3.put(k1, v3);
}
});
A variant that first copies data and then removes the differences:
Map<String, List<String>> hMap3 = new HashMap<>(hMap1);
hMap3.keys().retainAll(hMap2.keys());
hMap3.replaceAll((k, v) -> {
List<String> v3 = new ArrayList<>(v);
v3.retainAll(hMap2.get(k));
return v3;
});
1
Thanks very much for your help Federico. It works fine in Java 8.
– James Ngondo
yesterday
@JamesNgondo Glad it worked fine for you.
– Federico Peralta Schaffner
yesterday
add a comment |
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
It's much easier to do this at the XML level using XSLT (2.0 or higher) rather than doing it at the Java level. For example you can create a document that merges the two inputs supplied using
<xsl:variable name="inputs" select="doc('sample1.xml'), doc('sample2.xml')"/>
<xsl:template name="main">
<classes>
<xsl:for-each-group select="$inputs//class" group-by="@name">
<methods>
<xsl:for-each select="distinct-values(current-group()/methods/include/@name">
<include name="{.}"/>
</xsl:for-each>
</methods>
</xsl:for-each-group>
</classes>
</xsl:template>
This gives you the union of all the "include" elements for each name - I'm not sure if that's quite what you're asking for. It would be easier if you gave a high-level description of the problem you are trying to solve, rather than expressing it in terms of manipulations of Java hash tables.
add a comment |
up vote
1
down vote
It's much easier to do this at the XML level using XSLT (2.0 or higher) rather than doing it at the Java level. For example you can create a document that merges the two inputs supplied using
<xsl:variable name="inputs" select="doc('sample1.xml'), doc('sample2.xml')"/>
<xsl:template name="main">
<classes>
<xsl:for-each-group select="$inputs//class" group-by="@name">
<methods>
<xsl:for-each select="distinct-values(current-group()/methods/include/@name">
<include name="{.}"/>
</xsl:for-each>
</methods>
</xsl:for-each-group>
</classes>
</xsl:template>
This gives you the union of all the "include" elements for each name - I'm not sure if that's quite what you're asking for. It would be easier if you gave a high-level description of the problem you are trying to solve, rather than expressing it in terms of manipulations of Java hash tables.
add a comment |
up vote
1
down vote
up vote
1
down vote
It's much easier to do this at the XML level using XSLT (2.0 or higher) rather than doing it at the Java level. For example you can create a document that merges the two inputs supplied using
<xsl:variable name="inputs" select="doc('sample1.xml'), doc('sample2.xml')"/>
<xsl:template name="main">
<classes>
<xsl:for-each-group select="$inputs//class" group-by="@name">
<methods>
<xsl:for-each select="distinct-values(current-group()/methods/include/@name">
<include name="{.}"/>
</xsl:for-each>
</methods>
</xsl:for-each-group>
</classes>
</xsl:template>
This gives you the union of all the "include" elements for each name - I'm not sure if that's quite what you're asking for. It would be easier if you gave a high-level description of the problem you are trying to solve, rather than expressing it in terms of manipulations of Java hash tables.
It's much easier to do this at the XML level using XSLT (2.0 or higher) rather than doing it at the Java level. For example you can create a document that merges the two inputs supplied using
<xsl:variable name="inputs" select="doc('sample1.xml'), doc('sample2.xml')"/>
<xsl:template name="main">
<classes>
<xsl:for-each-group select="$inputs//class" group-by="@name">
<methods>
<xsl:for-each select="distinct-values(current-group()/methods/include/@name">
<include name="{.}"/>
</xsl:for-each>
</methods>
</xsl:for-each-group>
</classes>
</xsl:template>
This gives you the union of all the "include" elements for each name - I'm not sure if that's quite what you're asking for. It would be easier if you gave a high-level description of the problem you are trying to solve, rather than expressing it in terms of manipulations of Java hash tables.
answered yesterday
Michael Kay
107k657114
107k657114
add a comment |
add a comment |
up vote
0
down vote
You can try this:
Map<String, List<String>> resultMap = new HashMap<>();
for (String k: hMap1.keySet()) {
if (!hMap2.containsKey(k)) continue;
List<String> list = new ArrayList<>(hMap1.get(k));
list.retainAll(hMap2.get(k));
resultMap.put(k, list);
}
Thank you very much for your time and effort in helping out. This works very fine. Thanks.
– James Ngondo
yesterday
add a comment |
up vote
0
down vote
You can try this:
Map<String, List<String>> resultMap = new HashMap<>();
for (String k: hMap1.keySet()) {
if (!hMap2.containsKey(k)) continue;
List<String> list = new ArrayList<>(hMap1.get(k));
list.retainAll(hMap2.get(k));
resultMap.put(k, list);
}
Thank you very much for your time and effort in helping out. This works very fine. Thanks.
– James Ngondo
yesterday
add a comment |
up vote
0
down vote
up vote
0
down vote
You can try this:
Map<String, List<String>> resultMap = new HashMap<>();
for (String k: hMap1.keySet()) {
if (!hMap2.containsKey(k)) continue;
List<String> list = new ArrayList<>(hMap1.get(k));
list.retainAll(hMap2.get(k));
resultMap.put(k, list);
}
You can try this:
Map<String, List<String>> resultMap = new HashMap<>();
for (String k: hMap1.keySet()) {
if (!hMap2.containsKey(k)) continue;
List<String> list = new ArrayList<>(hMap1.get(k));
list.retainAll(hMap2.get(k));
resultMap.put(k, list);
}
answered yesterday
Donat
2855
2855
Thank you very much for your time and effort in helping out. This works very fine. Thanks.
– James Ngondo
yesterday
add a comment |
Thank you very much for your time and effort in helping out. This works very fine. Thanks.
– James Ngondo
yesterday
Thank you very much for your time and effort in helping out. This works very fine. Thanks.
– James Ngondo
yesterday
Thank you very much for your time and effort in helping out. This works very fine. Thanks.
– James Ngondo
yesterday
add a comment |
up vote
0
down vote
It's very easy in Java 8. You could stream both maps entries, filter entries whose key belongs to both maps and collect these entries to a new map, merging the values by intersecting them. In code:
Map<String, List<String>> hMap3 = Stream.of(hMap1, hMap2)
.flatMap(map -> map.entrySet().stream())
.filter(e -> hMap1.containsKey(e.getKey()) && hMap2.containsKey(e.getKey()))
.collect(Collectors.toMap(
Map.Entry::getKey,
e -> new ArrayList<>(e.getValue()),
(l1, l2) -> { l1.retainAll(l2); return l1; }));
Another possibility would be to iterate over hMap1
keys and if hMap2
contains the current key, put an entry into the new map that maps the key to the intersection of the values:
Map<String, List<String>> hMap3 = new HashMap<>();
hMap1.forEach((k1, v1) -> {
List<String> v2 = hMap2.get(k1);
if (v2 != null) {
List<String> v3 = new ArrayList<>(v1);
v3.retainAll(v2);
hMap3.put(k1, v3);
}
});
A variant that first copies data and then removes the differences:
Map<String, List<String>> hMap3 = new HashMap<>(hMap1);
hMap3.keys().retainAll(hMap2.keys());
hMap3.replaceAll((k, v) -> {
List<String> v3 = new ArrayList<>(v);
v3.retainAll(hMap2.get(k));
return v3;
});
1
Thanks very much for your help Federico. It works fine in Java 8.
– James Ngondo
yesterday
@JamesNgondo Glad it worked fine for you.
– Federico Peralta Schaffner
yesterday
add a comment |
up vote
0
down vote
It's very easy in Java 8. You could stream both maps entries, filter entries whose key belongs to both maps and collect these entries to a new map, merging the values by intersecting them. In code:
Map<String, List<String>> hMap3 = Stream.of(hMap1, hMap2)
.flatMap(map -> map.entrySet().stream())
.filter(e -> hMap1.containsKey(e.getKey()) && hMap2.containsKey(e.getKey()))
.collect(Collectors.toMap(
Map.Entry::getKey,
e -> new ArrayList<>(e.getValue()),
(l1, l2) -> { l1.retainAll(l2); return l1; }));
Another possibility would be to iterate over hMap1
keys and if hMap2
contains the current key, put an entry into the new map that maps the key to the intersection of the values:
Map<String, List<String>> hMap3 = new HashMap<>();
hMap1.forEach((k1, v1) -> {
List<String> v2 = hMap2.get(k1);
if (v2 != null) {
List<String> v3 = new ArrayList<>(v1);
v3.retainAll(v2);
hMap3.put(k1, v3);
}
});
A variant that first copies data and then removes the differences:
Map<String, List<String>> hMap3 = new HashMap<>(hMap1);
hMap3.keys().retainAll(hMap2.keys());
hMap3.replaceAll((k, v) -> {
List<String> v3 = new ArrayList<>(v);
v3.retainAll(hMap2.get(k));
return v3;
});
1
Thanks very much for your help Federico. It works fine in Java 8.
– James Ngondo
yesterday
@JamesNgondo Glad it worked fine for you.
– Federico Peralta Schaffner
yesterday
add a comment |
up vote
0
down vote
up vote
0
down vote
It's very easy in Java 8. You could stream both maps entries, filter entries whose key belongs to both maps and collect these entries to a new map, merging the values by intersecting them. In code:
Map<String, List<String>> hMap3 = Stream.of(hMap1, hMap2)
.flatMap(map -> map.entrySet().stream())
.filter(e -> hMap1.containsKey(e.getKey()) && hMap2.containsKey(e.getKey()))
.collect(Collectors.toMap(
Map.Entry::getKey,
e -> new ArrayList<>(e.getValue()),
(l1, l2) -> { l1.retainAll(l2); return l1; }));
Another possibility would be to iterate over hMap1
keys and if hMap2
contains the current key, put an entry into the new map that maps the key to the intersection of the values:
Map<String, List<String>> hMap3 = new HashMap<>();
hMap1.forEach((k1, v1) -> {
List<String> v2 = hMap2.get(k1);
if (v2 != null) {
List<String> v3 = new ArrayList<>(v1);
v3.retainAll(v2);
hMap3.put(k1, v3);
}
});
A variant that first copies data and then removes the differences:
Map<String, List<String>> hMap3 = new HashMap<>(hMap1);
hMap3.keys().retainAll(hMap2.keys());
hMap3.replaceAll((k, v) -> {
List<String> v3 = new ArrayList<>(v);
v3.retainAll(hMap2.get(k));
return v3;
});
It's very easy in Java 8. You could stream both maps entries, filter entries whose key belongs to both maps and collect these entries to a new map, merging the values by intersecting them. In code:
Map<String, List<String>> hMap3 = Stream.of(hMap1, hMap2)
.flatMap(map -> map.entrySet().stream())
.filter(e -> hMap1.containsKey(e.getKey()) && hMap2.containsKey(e.getKey()))
.collect(Collectors.toMap(
Map.Entry::getKey,
e -> new ArrayList<>(e.getValue()),
(l1, l2) -> { l1.retainAll(l2); return l1; }));
Another possibility would be to iterate over hMap1
keys and if hMap2
contains the current key, put an entry into the new map that maps the key to the intersection of the values:
Map<String, List<String>> hMap3 = new HashMap<>();
hMap1.forEach((k1, v1) -> {
List<String> v2 = hMap2.get(k1);
if (v2 != null) {
List<String> v3 = new ArrayList<>(v1);
v3.retainAll(v2);
hMap3.put(k1, v3);
}
});
A variant that first copies data and then removes the differences:
Map<String, List<String>> hMap3 = new HashMap<>(hMap1);
hMap3.keys().retainAll(hMap2.keys());
hMap3.replaceAll((k, v) -> {
List<String> v3 = new ArrayList<>(v);
v3.retainAll(hMap2.get(k));
return v3;
});
edited yesterday
answered yesterday
Federico Peralta Schaffner
21.1k33067
21.1k33067
1
Thanks very much for your help Federico. It works fine in Java 8.
– James Ngondo
yesterday
@JamesNgondo Glad it worked fine for you.
– Federico Peralta Schaffner
yesterday
add a comment |
1
Thanks very much for your help Federico. It works fine in Java 8.
– James Ngondo
yesterday
@JamesNgondo Glad it worked fine for you.
– Federico Peralta Schaffner
yesterday
1
1
Thanks very much for your help Federico. It works fine in Java 8.
– James Ngondo
yesterday
Thanks very much for your help Federico. It works fine in Java 8.
– James Ngondo
yesterday
@JamesNgondo Glad it worked fine for you.
– Federico Peralta Schaffner
yesterday
@JamesNgondo Glad it worked fine for you.
– Federico Peralta Schaffner
yesterday
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53238531%2fhow-to-compare-two-hashmapstring-liststring-with-list-items-as-values-to-ch%23new-answer', 'question_page');
}
);
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
You can first start with a brute force approach.
– Sid
yesterday
Implement a Comparator
– Anastasios Moraitis
yesterday
You can use reverse lookup where instead of class as key, use method as key
– mani deepak
yesterday