can map be compare with arraylist of string in java
private Map<String, String> checkInScopeLobs(Map<String, String> allLobsChkBx)
{
Map<String, String> inScopeLobs = new HashMap<String, String>();;
for (Map.Entry<String, String> entry : allLobsChkBx.entrySet())
{
if(entry.getKey().contains("1") || entry.getKey().contains("2") || entry.getKey().contains("3")){
inScopeLobs.put(entry.getKey(), entry.getValue());
}
}
return inScopeLobs;
}
is this a correct way ?
You can make use of keySet(). This method returns a Set of keys (for more info, Docs from Oracle about Map). This means less overhead than iterating over your whole map. In the following case you'll only request values of matching keys.
There are some other faults like a double semicolon and since JDK7 you don't have to define your map when initializing.
private Map<String, String> checkInScopeLobs(Map<String, String> allLobsChkBx) {
Map<String, String> inScopeLobs = new HashMap();
List<String> keys = Arrays.asList( { "1", "2", "3" } );
for(String key : allLobsChkBx.keySet()) {
if(keys.contains(key)) {
inScopeLobs.put(key, allLobsChkBx.get(key));
}
}
return inScopeLobs;
}
Why aren't you using an Integer instead of a String, since you're only storing numbers.
Since key is String you can use matches method from String class
for (Map.Entry<String, String> entry : allLobsChkBx.entrySet())
{
if(entry.getKey().matches(".*[123].*")){
inScopeLobs.put(entry.getKey(), entry.getValue());
}
}
Actually there are no such methods, but you can try this approach:
Map<String, String> allLobsChkBx = new HashMap<String, String>(4);
allLobsChkBx.put("1", "A");
allLobsChkBx.put("2", "B");
allLobsChkBx.put("3", "C");
allLobsChkBx.put("4", "D");
allLobsChkBx.put("5", "E");
System.out.println("Before retain: " + allLobsChkBx);
List<String> keysToRetain = Arrays.asList(new String[] { "1", "2", "3" });
allLobsChkBx.keySet().retainAll(keysToRetain);
System.out.println("After retain: " + allLobsChkBx);
It will produce following output:
Before retain: {3=C, 2=B, 1=A, 5=E, 4=D}
After retain: {3=C, 2=B, 1=A}
Related
I have an object with structure
List<Map<String(k1), Map<String(k2), String(v2)>>>
I need to convert the above list to
List<Map<String(k2), Map<String(k1), String(v2)>>>
I am stuck on how do i get the nested map using construct like
serviceResults.stream().map((k, v) -> ????)
that will allow me to swap the keys. Is it possible to do it in a way without using loops using Java 8 streams?
Additional Info
This is the code that uses loop construct
List<Map<String, Map<String, String>>> serviceResults = new ArrayList<>();
//Populate the above list
Map<String, Map<String, String>> swpMapOuter = new HashMap<>();
Map<String, String> swpMapInner = new HashMap<>();
for (Map<String, Map<String, String>> stringMapMap : serviceResults) {
for (Map.Entry<String, Map<String, String>> s : stringMapMap.entrySet()) {
String key1 = s.getKey();
Map<String, String> value1 = s.getValue();
for (Map.Entry<String, String> s1 : value1.entrySet()) {
String key2 = s1.getKey();
String value2 = s1.getValue();
swpMapInner.put(key1, value2);
swpMapOuter.put(key2, swpMapInner);
}
}
}
System.out.println("swpMapOuter " + swpMapOuter);
Below is the code with forEach, instead of for loops, but was wondering, if it could be implemented using Stream constructs
Map<String, Map<String, String>> swpMapOuter2 = new HashMap<>();
Map<String, String> swpMapInner2 = new HashMap<>();
serviceResults.forEach((stringMapMap) -> {
stringMapMap.entrySet().forEach((s) -> {
String key1 = s.getKey();
Map<String, String> value1 = s.getValue();
value1.entrySet().forEach((s1) -> {
String key2 = s1.getKey();
String value2 = s1.getValue();
swpMapInner2.put(key1, value2);
swpMapOuter2.put(key2, swpMapInner2);
});
});
});
System.out.println("swpMapOuter2 " + swpMapOuter2);
I have a list of Maps as below:
List<Map<String,Object>> someObjectsList = new ArrayList<Map<String,Object>>();
I am storing the following data in each HashMap
key value
2017-07-21 2017-07-21-07.33.28.429340
2017-07-24 2017-07-24-01.23.33.591340
2017-07-24 2017-07-24-01.23.33.492340
2017-07-21 2017-07-21-07.33.28.429540
I want to iterate through the list of HashMaps and check if the key matches with the first 10 characters of any of the HashMap value, then I want to store those keys and values in the following format. i.e. by using the telemeter 'comma'. The ultimate aim is to group the unique keys of the HashMaps and their relative values (if the key matches with the first 10 characters of any of the HashMap value) in a new HashMap.
key value
2017-07-21 2017-07-21-07.33.28.429340,2017-07-21-07.33.28.429540
2017-07-24 2017-07-24-01.23.33.591340,2017-07-24-01.23.33.492340
I am trying with following java code using StringJoiner, but not getting the results as expected. Any clue on how to frame the logic here?
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringJoiner;
public class SampleOne {
public static void main(String[] args) {
// TODO Auto-generated method stub
List<Map<String, Object>> someObjectsList = new ArrayList<Map<String, Object>>();
Map<String, Object> mapOne = new HashMap<String, Object>();
mapOne.put("2017-07-21", "2017-07-21-07.33.28.429340");
Map<String, Object> mapTwo = new HashMap<String, Object>();
mapTwo.put("2017-07-24", "2017-07-24-01.23.33.591340");
Map<String, Object> mapThree = new HashMap<String, Object>();
mapThree.put("2017-07-24", "2017-07-24-01.23.33.492340");
Map<String, Object> mapFour = new HashMap<String, Object>();
mapFour.put("2017-07-21", "2017-07-21-07.33.28.429540");
someObjectsList.add(mapOne);
someObjectsList.add(mapTwo);
someObjectsList.add(mapThree);
someObjectsList.add(mapFour);
for (Map map : someObjectsList) {
StringJoiner sj = new StringJoiner(",");
for (Object key : map.keySet()) {
String value = ((String) map.get(key));
String date = value.substring(0, Math.min(value.length(), 10));
//System.out.println(str);
//System.out.println(value);
if(key.equals(date)) {
sj.add(value);
System.out.println(sj.toString());
}
}
}
}
}
output:
2017-07-21-07.33.28.429340
2017-07-24-01.23.33.591340
2017-07-24-01.23.33.492340
2017-07-21-07.33.28.429540
Make use of the .merge function:
Map<String, Object> finalMap = new HashMap<String, Object>();
for (Map map : someObjectsList) {
for (Object key : map.keySet()) {
String value = ((String) map.get(key));
finalMap.merge((String) key, value, (k, v) -> k + "," + v);
}
}
which outputs:
{2017-07-21=2017-07-21-07.33.28.429340,2017-07-21-07.33.28.429540,
2017-07-24=2017-07-24-01.23.33.591340,2017-07-24-01.23.33.492340}
The same can be achieved by the following one-liner:
someObjectsList.stream()
.flatMap(i -> i.entrySet().stream())
.collect(Collectors.toMap(Entry::getKey, Entry::getValue,
(k, v) -> k + "," + v));
On your code, you are using different StringJoiner on each map. So, it's creating a new instance of it.
You can save your keys on a map. An example code:
(Edit: I did not remove your StringJoiner part.)
public static void main(String[] args) {
// TODO Auto-generated method stub
List<Map<String, Object>> someObjectsList = new ArrayList<Map<String, Object>>();
Map<String, Object> mapOne = new HashMap<String, Object>();
mapOne.put("2017-07-21", "2017-07-21-07.33.28.429340");
Map<String, Object> mapTwo = new HashMap<String, Object>();
mapTwo.put("2017-07-24", "2017-07-24-01.23.33.591340");
Map<String, Object> mapThree = new HashMap<String, Object>();
mapThree.put("2017-07-24", "2017-07-24-01.23.33.492340");
Map<String, Object> mapFour = new HashMap<String, Object>();
mapFour.put("2017-07-21", "2017-07-21-07.33.28.429540");
someObjectsList.add(mapOne);
someObjectsList.add(mapTwo);
someObjectsList.add(mapThree);
someObjectsList.add(mapFour);
Map<String, Object> outputMap = new HashMap<String, Object>();
for (Map map : someObjectsList) {
StringJoiner sj = new StringJoiner(",");
for (Object key : map.keySet()) {
String value = ((String) map.get(key));
String date = value.substring(0, Math.min(value.length(), 10));
//System.out.println(str);
//System.out.println(value);
if(key.equals(date)) {
sj.add(value);
System.out.println(sj.toString());
if(outputMap.containsKey(key)) {
String str = (String) map.get(key);
str = str + "," + value;
outputMap.put((String)key, str);
} else {
outputMap.put((String)key, value);
}
}
}
}
for (String map : outputMap.keySet()) {
System.out.println(map + " " + outputMap.get(map));
}
}
You are looking for the grouping behavior of processing a List. You can use the advantage of java-stream since java-8. In any case, you need a new Map to store the values in order to print them. :
someObjectsList.stream()
.flatMap(i -> i.entrySet().stream()) // flatmapping to entries
.collect(Collectors.groupingBy(Entry::getKey)) // grouping them using the key
In case you want to use for-loops. In this case it is harder since the more entries might appear in each List item:
final Map<String, List<Object>> map = new HashMap<>();
for (Map<String, Object> m: someObjectsList) { // iterate List<Map>
for (Entry<String, Object> entry: m.entrySet()) { // iterate entries of each Map
List<Object> list;
final String key = entry.getKey(); // key of the entry
final Object value = entry.getValue(); // value of the entry
if (map.containsKey(key)) { // if the key exists
list = map.get(key); // ... use it
} else {
list = new ArrayList<>(); // ... or else create a new one
}
list.add(value); // add the new value
map.put(key, list); // and add/update the entry
}
}
Printing out of Map<String, List<Object>> map in both cased will produce the following output:
2017-07-21=[2017-07-21-07.33.28.429340, 2017-07-21-07.33.28.429540],
2017-07-24=[2017-07-24-01.23.33.591340, 2017-07-24-01.23.33.492340]
Any reason you're using Object over String and avoiding safety checks? That said, it's not "the first 10 characters", you want to see if value starts with key full-stop (all your keys are 10 characters). So in that case you can just do if (value.startsWith(key)) { ... }. Don't forget your newlines if the stringjoiner wasn't full. Lastly, you don't need a List, a Map can hold multiple keys at once. An alternative way of doing it:
//LinkedHashMap will preserve our insertion order
Map<String, String> map = new LinkedHashMap<>();
map.put("2017-07-21", "2017-07-21-07.33.28.429340");
map.put("2017-07-24", "2017-07-24-01.23.33.591340");
//note duplicates are overwritten, but no value change here
map.put("2017-07-24", "2017-07-24-01.23.33.492340");
map.put("2017-07-21", "2017-07-21-07.33.28.429540");
// You can also use Java 8 streams for the concatenation
// but I left it simple
List<String> matches = map.entrySet()
.filter(e -> e.getValue().startsWith(e.getKey())
.collect(Collectors.toList());
String concatenated = String.join("\n", matches);
If you wanted to generate that string without streams, it would look like this (again, not using #entrySet for simplicity, but it would be more efficient here):
List<String> matches = new ArrayList<>();
StringJoiner joiner = new StringJoiner("\n");
for (String key : map.keySet()) {
String value = map.get(key);
if (value.startsWith(key)) {
joiner.add(value);
}
}
//joiner#toString will give the expected result
I have a hashmap with some keys pointing to same values. I want to find all the values that are equal and print the corresponding keys.
This is the current code that I have:
Map<String, String> map = new HashMap<>();
map.put("hello", "0123");
map.put("hola", "0123");
map.put("kosta", "0123");
map.put("da", "03");
map.put("notda", "013");
map.put("twins2", "01");
map.put("twins22", "01");
List<String> myList = new ArrayList<>();
for (Map.Entry<String, String> entry : map.entrySet()) {
for (Map.Entry<String, String> entry2 : map.entrySet()){
if (entry.getValue().equals(entry2.getValue()))
{
myList.add(entry.getKey());
}
}
}
The current code adds the duplicates two times into the list, however it also adds every key one time.
Thanks.
You can use streams to retrive duplicates in this way:
List<String> myList = map.stream()
.filter(n -> Collections.frequency(map.values(), n) > 1)
.collect(Collectors.toList());
And then, you can print this out with:
myList.foreach(System.out::println);
Build a Map<VALUE, List<KEY>>, i.e. a Map<String, List<String>>.
Example
Map<String, String> map = new HashMap<>();
map.put("hello", "0123");
map.put("hola", "0123");
map.put("kosta", "0123");
map.put("da", "03");
map.put("notda", "013");
map.put("twins2", "01");
map.put("twins22", "01");
map.entrySet().stream()
.collect(Collectors.groupingBy(Entry::getValue,
Collectors.mapping(Entry::getKey, Collectors.toList())))
.entrySet().stream()
.filter(e -> e.getValue().size() > 1)
.forEach(System.out::println);
Output
01=[twins22, twins2]
0123=[kosta, hello, hola]
Without the filter(), the result would be:
01=[twins22, twins2]
013=[notda]
03=[da]
0123=[kosta, hello, hola]
If you want a solution beside to Stream API;
public static void duplicatedValuesMap() {
Map<String, String> map = new HashMap<>();
map.put("hello", "0123");
map.put("hola", "0123");
map.put("kosta", "0123 test");
map.put("da", "03");
map.put("notda", "013");
map.put("twins2", "01");
map.put("twins22", "01");
HashMap<String, List<String>> valueToKeyMapCounter = new HashMap<>();
for (Map.Entry<String, String> entry : map.entrySet()) {
if (valueToKeyMapCounter.containsKey(entry.getValue())) {
valueToKeyMapCounter.get(entry.getValue()).add(entry.getKey());
} else {
List<String> keys = new ArrayList<>();
keys.add(entry.getKey());
valueToKeyMapCounter.put(entry.getValue(), keys);
}
}
for (Map.Entry<String, List<String>> counterEntry : valueToKeyMapCounter.entrySet()) {
if (counterEntry.getValue().size() > 1) {
System.out.println("Duplicated Value:" + counterEntry.getKey() + " for Keys:" + counterEntry.getValue());
}
}
}
I think other answers already good to solve the question, i support another method to do just for extended thinking.This method need use Guava's MutliMap interface:
// init the input map
Map<String, String> map = new HashMap<>();
map.put("hello", "0123");
map.put("hola", "0123");
map.put("kosta", "0123");
map.put("da", "03");
map.put("notda", "013");
map.put("twins2", "01");
map.put("twins22", "01");
// swap key and value of the input map,since different key has same value
// so we need Multimap
Multimap<String, String> container = ArrayListMultimap.create();
map.entrySet().forEach(entry -> container.put(entry.getValue(), entry.getKey()));
container.keySet().stream()
.filter(s -> container.get(s).size() > 1).
forEach(System.out::println);
output:
01
0123
There are 2 LinkedHashMaps. I have to check if both LinkedHashMaps have same keys & values. If one LinkedHashMap contains extra keys + values then it should get printed or stored in 3rd LinkedHashMap. If any of the key or value is different in 2nd LinkedHashMap then it should be notified (print in console)
Eg
Map1 contains {A-a, B-b, C-c}
Map2 contains {A-a, B-r, C-c, Z-z}
So here 3rd LinkedHashMap should contain {Z-z} as it contains extra key and
{B-r} should get printed as it is modified
you can use this class :)
public class MapCompare {
private LinkedHashMap<String, String> differencesMap;
private LinkedHashMap<String, String> extraMap;
private void main(LinkedHashMap<String, String> map1, LinkedHashMap<String, String> map2) {
this.differencesMap = new LinkedHashMap<>();
this.extraMap = new LinkedHashMap<>();
Set<Map.Entry<String, String>> set1 = ((LinkedHashMap<String, String>) map1.clone()).entrySet();
Set<Map.Entry<String, String>> set2 = ((LinkedHashMap<String, String>) map2.clone()).entrySet();
set1.removeAll(set2);
compare(set1, map2);
set1 = map1.entrySet();
set2.removeAll(set1);
compare(set2, map1);
}
private LinkedHashMap<String, String> getDifferencesMap() {
return differencesMap;
}
private LinkedHashMap<String, String> getExtraMap() {
return extraMap;
}
private void compare(Set<Map.Entry<String, String>> set, LinkedHashMap<String, String> map) {
for (Map.Entry<String, String> entry : set) {
String key = entry.getKey();
String value = entry.getValue();
if (map.containsKey(key) || map.containsValue(value)) {
differencesMap.put(key, value);
} else {
extraMap.put(key, value);
}
}
}
public static void main(String[] args) {
LinkedHashMap<String, String> map1 = new LinkedHashMap<>();
map1.put("A", "a");
map1.put("B", "b");
map1.put("C", "c");
LinkedHashMap<String, String> map2 = new LinkedHashMap<>();
map2.put("A", "a");
map2.put("C", "c");
map2.put("B", "r");
map2.put("Z", "z");
MapCompare mapCompare = new MapCompare();
mapCompare.main(map1,map2);
System.out.println("diff: " + mapCompare.getDifferencesMap());
System.out.println("extra: " + mapCompare.getExtraMap());
}
}
I have a method which is returning List<Map<String,Object>>.
How to iterate over a list like List<Map<String,Object>>?
It sounds like you're looking for something like this:
List<Map<String, Object>> list; // this is what you have already
for (Map<String, Object> map : list) {
for (Map.Entry<String, Object> entry : map.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
}
}
List<Map<String, Object>> list = getMyMap();
for (Map<String, Object> map : list) {
for (Map.Entry<String, Object> entry : map.entrySet()) {
System.out.println(entry.getKey() + " - " + entry.getValue());
}
}
Loop through list of maps
Handle map entries
with java 1.8 (8) you can re-write it like:
list.forEach(item ->
item.forEach((k, v) -> System.out.println(k + ": " + (String)v)
);
I'm posting you one simple Example of List<Map<String,Object>>.
public static void main(String[] args){
Map<String,Object> map1 = new HashMap<>();
map1.put("Map1 Key1", (Object) "Map1 value1");
map1.put("Map1 Key2", (Object) "Map1 value2");
Map<String,Object> map2 = new HashMap<>();
map2.put("Map2 Key1", (Object) "Map2 value1");
map2.put("Map2 Key2", (Object) "Map2 value2");
List<Map<String,Object>> list = new ArrayList<>();
list.add(map1);
list.add(map2);
list.stream().forEach(mapsData->{
mapsData.entrySet().forEach(mapData->{
System.out.println("Key:"+mapData.getKey()+ " Value:"+mapData.getValue());
});
});
}
This should work:
List<Map<String, Object>> list = ...
for (Map<String, Object> map : list)
{
...
}
You can also use an iterator or the get method within a for loop to access the elements within the List.
Map<String, String> map = new HashMap<>();
map.put("First", "1");
map.put("Second", "2");
map.put("third", "3");
map.put("four", "4");
// here is the logic
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println(entry.getKey() + " - " + entry.getValue());
}
This is an easy way to iterate over a list of Maps as my starting point. My List had one Map object inside with 3 values
List<Map<String, Object>>
using Java's functional programming in a rather short and succinct manner. The purpose here was to pull out all the maps stored in a list and print them out. I could have also collected the values etc.
answerListOfMaps.stream().map(map -> map.entrySet())
.forEach(System.out::println );
output in Eclipse IDE console looked like this:
[isAllowed=true, isValid=true, cardNumber=672xxxxxxxxxxx]
x's for Obfuscation
alternate way:
answerListOfMaps.stream().flatMap(map -> map.entrySet().stream())
.forEach( entry -> System.out.println(entry.getKey() + ":" + entry.getValue()) );
console:
isAllowed:true
isValid:true
cardNumber:672xxxxxxxxxxx