I'm a beginner,
I want to create a new map hm3 by using two old maps hm1 and hm2 and in that map I need value of second map as key and value of first map as value
For example : if map hm1 is containing a1 as key1 and abc as value1 and it also containing a2 as key2 and xyz as value2 and there is another map hm2 which contains a1 as key1 and b1 as value1 and also containing a2 as key2 and b2 as value2 then in the map hm3 I need b1 as key1 and abc as value1 and b2 ans key2 and xyz as value2
public class MapInterchange {
public static void main(String[] args) {
HashMap<String, String> hm1 = new HashMap<String, String>();
Map.Entry m1;
hm1.put("a1", "abc");
hm1.put("a2", "xyz");
for (Map.Entry m : hm1.entrySet()) {
System.out.println(m.getKey() + " " + m.getValue());
}
HashMap<String, String> hm2 = new HashMap<String, String>();
hm2.put("a1", "b1");
hm2.put("a2", "b2");
for (Map.Entry m : hm2.entrySet()) {
System.out.println(m.getKey() + " " + m.getValue());
}
HashMap<Object, Object> hm3 = new HashMap<Object, Object>();
Iterator itr = ((Set<Entry<String, String>>) hm1).iterator();
while (itr.hasNext()) {
hm3.put(((Entry) hm2).getValue(), ((Entry) hm1).getValue());
}
for (Map.Entry m : hm3.entrySet()) {
System.out.println(m.getKey() + " " + m.getValue());
}
}
}
The exception I'm getting is : Exception in thread "main" java.lang.ClassCastException: java.util.HashMap cannot be cast to java.util.Set
at com.sid.MapInterchange.main(MapInterchange.java:34)
Please provide the corrected code, I will be very thankful
You can't cast a HashMap to a Set of entries. Use the entrySet method.
Iterator<Map.Entry<String,String>> itr = hm1.entrySet().iterator();
while (itr.hasNext()) {
Map.Entry<String,String> entry = itr.next();
hm3.put(entry.getKey(), entry.getValue());
}
EDIT: I'm not sure this code does what you want to do, but it overcomes your error. It's not clear what you are trying to swap.
If the mapping of the values is based on the keys, your code should be :
Iterator<Map.Entry<String,String>> itr = hm1.entrySet().iterator();
while (itr.hasNext()) {
Map.Entry<String,String> entry = itr.next();
hm3.put(hm2.get(entry.getKey()), entry.getValue());
}
This assumes that all the keys of hm1 appear in hm2 (otherwise you'll have a null key in your output Map).
Related
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 am trying to set a hashmap to have key as string and a list array as value. Is it possible? and how do I set the list into the value?
HashMap<String, List<String>> foo = new HashMap<String, List<String>>();
foo.put("key1",{"key1_value1","key1_value2"});
You can do the following
Map<String, List<String>> foo = new HashMap<String, List<String>>();
List<String> list = new ArrayList<String>();
list.add("key1_value1");
list.add("key1_value2");
foo.put("key1",list);
foo.put("key", Arrays.asList("key1_val1", "key1_val2"));
You have to use a data structure like ArrayList or just an array maybe to represent the list of strings as value.
You can use the following with a List;
foo.put("key", Arrays.asList("key1_val1", "key1_val2"));
where foo is of type Map<String, List<String>>
Or you the following with an array;
foo.put("key", new String[]{"key1_val1", "key1_val2"});
where foo is of type Map<String, String[]>
Map<String, List<String>> foo = new HashMap<String, List<String>>();
List<String> list = new ArrayList<String>();
list.add("value1");
list.add("value2");
foo.put("key1", list);
for (Entry<String, List<String>> entry : foo.entrySet()) {
String key = entry.getKey();
List<String> valueList = entry.getValue();
System.out.println("key = " + key);
for (String value : valueList) {
System.out.println("value = " + value);
}
}
Output
key = key1
value = value1
value = value2
I have a hashmap which contains student id as key and some string as value.
It contains data like
a abc.txt
b cde.txt
d abc.txt
I want to find the duplicate values in map and replace them with genreic values. I want a map like
a abc.txt
b cde.txt
d abc_replacevalue.txt
I have tried with the code but its not working
Map<String,String> filemap = new HashMap<String,String>();
// filemap is the original hash map..
Set<String> seenValues = new HashSet<String>();
Map<String, String> result = new HashMap<String, String>();
for (Map.Entry<String, String> entry : filemap.entrySet()) {
String value = entry.getValue();
if (seenValues.contains(value)) {
value = "updated"; // update value here
}
result.put(entry.getKey(), value);
seenValues.add(value);
}
for (String key : result.keySet() ) {
String value = result.get( key );
System.out.println(key + " = " + value);
}
The output is still the same
a abc.txt
b cde.txt
d abc.txt
You can generate a new map from an existing one, checking every new value that you come across to see if it has already been seen:
Set<String> seenValues = new HashSet<String>();
Map<String, String> result = new HashMap<String, String>();
for (Map.Entry<String, String> entry : original.entrySet()) {
String value = entry.getValue();
if (seenValues.contains(value)) {
value = ...; // update value here
}
result.put(entry.getKey(), value);
seenValues.add(value);
}
i want to create a list that each row contain an array like this :
key1 ->value1
key2 ->value2
key3 ->value3
(key and value are string)
How can i do this ?
If your key must be a String, then you want to use a Map rather than an array. And you want/need a List<Map<String, String>>.
Here's an example:
//declaring and initializing the list of maps
//line below works for Java 7
//List<Map<String, String>> listOfMaps = new ArrayList<>();
//if you want/need to use Java 6 then use the following
List<Map<String, String>> listOfMaps = new ArrayList<Map<String, String>>();
//declaring, initializing and filling a map
//line below works for Java 7
//Map<String, String> map1 = new HashMap<>();
//if you want/need to use Java 6 then use the following
Map<String, String> map1 = new HashMap<String, String>();
map1.put("name", "Luiggi");
map1.put("lastname", "Mendoza");
map1.put("maintag", "Java");
//declaring, initializing and filling another map
//line below works for Java 7
//Map<String, String> map2 = new HashMap<>();
//if you want/need to use Java 6 then use the following
Map<String, String> map2 = new HashMap<String, String>();
map2.put("name", "Foo");
map2.put("lastname", "Bar");
map2.put("maintag", "Scala"); //I have nothing against scala
//add maps into the list
listOfMaps.add(map1);
listOfMaps.add(map2);
//Show contents of the list and map
System.out.println(listOfMaps);
//Traverse each element of the List to access key and value
int index = 0;
//it is better to use Iterator or enhanced for each than using List#get(index)
for (Map<String, String> map : listOfMaps) {
System.out.println("Printing element " + index++);
for(Map.Entry<String, String> entry : map.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
System.out.println("--------------------------");
}
You can use an
ArrayList<Map<String, String>>()
This would have the following structure
List index 0: Key1 -> value 1, Key2 -> value 2
List index 1: Key3 -> value 3
So to put a key value pair:
List<Map<String, String>> list = new ArrayList<Map<String, String>>();
Map<String, String> map = new HashMap<String, String>();
map.put(key, value);
map.put(key1, value1);
list.add(map);
So to get a value from a key in the first index of the list:
String value = list.get(0).get(key)
Map<String, String> map = new HashMap<String, String>();
map.put("key1", "1");
map.put("key2", "2");
Map<String, String> anotherMap = new HashMap<String, String>();
anotherMap .put("key3", "3");
anotherMap .put("key4", "4");
List<Map<String, String>> listOfMaps = new ArrayList<Map<String, String>>();
listOfMaps.add(map);
listOfMaps.add(anotherMap);
Why do you need this list? What do you need to do with it? Or is this just an exercise?
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