Issue to get data from a collection - java

I am trying to get data out of a list,but facing some issue while getting the data.
List<Field> errorFieldList;
Set<String> formValidationResult = new HashSet<String>();
Here the data added to validationResults is like and errorFieldList size is two having Id and type
validationResults.put(errorFieldList, formValidationResult);
public ValidationResponseErrorView(
Map<Object, Set<String>> validationResults, String exceptionMessage) {
if (validationResults.size() > 0) {
for (Map.Entry<Object, Set<String>> entrySet : validationResults
.entrySet()) {
Map<String, Object> fieldResultsMap = new HashMap<String, Object>();
Object objField = entrySet.getKey();
if (objField instanceof List) {
for (int i = 0; i < ((List<Map<String, Object>>) objField)
.size(); i++) {
LOGGER.info("in array list----" + objField);
}
}
}
}
}
I am not sure how to get data out of objField.

Your code is really hard to read and contains a lot of inconsistencies. Especially in your constructor you declare validationResults as
Map<Object, Set<String>> validationResults
But in your introduction you declare it as
List<Field> errorFieldList;
Set<String> formValidationResult = new HashSet<String>();
validationResults.put(errorFieldList, formValidationResult);
which means your Object is a List<Field>. So now you can simply use:
objField.get(i);
to retrieve the values, where i is your index you iterate over. HOWEVER: your code probably won't compile, since you try to cast the List<Field> to List<Map<String, Object>> in the 2nd for loop.
Simply put: rework the code, A Map has getter methods for the key and over a Set you need to iterate. Check first what data structure you need. Don't nest too deep.

List< Map< String, Object>> objField would return you a List which has elements of type Map<String, Object>. To get value from this use:
Map<String,Object> mapOut = ((List<Map<String, Object>>) objField).get(i);
Set<String> keySet = mapOut.keySet();
Iterator<String> itr = keySet.iterator();
while(itr.hasNext()){
Object outObject = mapOut.get(itr.next());
LOGGER.info("Object"+ outObject);
}

Related

get key and value from HashMap within ArrayList

I have a file that i get all the data and separate it into a HashMap.
The file looks something like this below.
Before the : is the key and after is the value
key1: 1
key2: 2
key3: 3
this is the code that puts the file data into the map ArrayList:
protected List<Map<String, String>> yaml_parse(BufferedReader filename) throws IOException{
String result;
List<Map<String, String>> list = new ArrayList<Map<String, String>>();
while ((result = filename.readLine()) != null) {
Map<String, String> map = new HashMap<String, String>();
String key = result.substring(0, result.indexOf(":"));
String value = result.substring(result.lastIndexOf(":") + 2);
map.put(key, value);
list.add(map);
}
return list;
}
in another class where i call the function and println, this is the output
[{key1=1}, {key2=2}, {key3=3}]
So my Main question is, how do i get key1 and have it return its value?
I don't understand why you are creating a List of maps. A Map will let you put several key value pairs. Here is a way that would work:
protected Map<String, String> yaml_parse(BufferedReader filename) throws IOException{
String result;
Map<String, String> map = new HashMap<String, String>();
while ((result = filename.readLine()) != null) {
//keyValue[0] = key, keyValue[1] = value
String[] keyValue = result.split(": ");
map.put(keyValue[0], keyValue[1]);
}
return map;
}
And you would use it like this:
Map<String, String> map = yaml_parse("myFile.yaml");
String key1Value = map.get("key1"); //Stores key1's value into key1Value
I think you might be using the wrong data structure. From your question, it seems like you want a Map only, not a List of Maps.
You should look at changing your List<Map> to a Map. You can do this using:
Map<String, String> map = list.stream()
.flatMap(m -> m.entrySet().stream())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
If you want to work with your current data structure, you can get the required value like this:
private Optional<String> getValue(List<Map<String, String>> list, String key) {
return list.stream()
.filter(m -> m.containsKey(key))
.map(m -> m.get(key))
.findFirst();
}
and use it as follows:-
Optional<String> value = getValue(list, "key2");
System.out.println(value.orElse(null));
So if you are interested in using java-8, if list of map contains any of entry with key as key1 will return the first entry value else it will return the default value
list.stream().flatMap(map->map.entrySet().stream().filter(entry->entry.getKey().equals("key1"))).findFirst()
.orElse(new AbstractMap.SimpleEntry("key1", "default value")).getValue();
Just by using normal for loop
for(Map<String, String> map : list) {
if(map.containsKey("key1")) {
result = map.get("key1");
break;
}
}
Are you sure this is the data structure you want?
A map can contain more than 1 key/value pair. Why not have a single hashmap here, containing all 3 key/value pairs, at which point, you can just do:
map.get("key1")
and it'll still be fast even if you have millions of these.
If you are making single-size maps and putting them into an arraylist because you want to preserve order, use LinkedHashMap. If you need to be capable of dealing with repeated keys, use guava's Multimap, or make a Map<String, List<String>>.

How to add a value to a list of values for a single key in a hashmap (Java)

I have written this:
HashMap<String, String> map1 = new HashMap<String, String>();
Map<String, ArrayList<String>> map2 = new HashMap<String, ArrayList<String>>();
i am trying to allow more then 1 value for each key in a hashmap. so if the first key is '1', i want to allow '1' to be paired with values '2' and '3'.
so it be like:
1 --> 2
|--> 3
but when I do:
map2.put(key, value);
it gives error that says "incompatible types" and it can not be converted to ArrayList and it says the error is at the value part of the line.
If you are using Java 8, you can do this quite easily:
String key = "someKey";
String value1 = "someValue1";
String value2 = "someValue2";
Map<String, List<String>> map2 = new HashMap<>();
map2.computeIfAbsent(key, k -> new ArrayList<>()).add(value1);
map2.computeIfAbsent(key, k -> new ArrayList<>()).add(value2);
System.out.println(map2);
The documentation for Map.computeIfAbsent(...) has pretty much this example.
In map2 you need to add ArrayList (you declared it as Map<String, ArrayList<String>> - the second one is the value type) only, that's why it gives you incompatible types.
You would need to do initialize the key with an ArrayList and add objects to it later:
if (!map2.containsKey(key)) {
map2.put(key, new ArrayList<String>());
}
map2.get(key).add(value);
Or you could use Multimap from guava, then you can just map2.put and it won't overwrite your values there but add to a list.
You are little bit away from what you are trying to do.
Map<String, ArrayList<String>> map2 = new HashMap<String, ArrayList<String>>();
this will allow only String as key and an ArrayList as value. So you have to try something like:
ArrayList<String> value=new ArrayList<String>();
value.add("2");
value.add("3");
map2.put("1", value);
When retrieving you also have to follow ans opposite procedure.
ArrayList<String> valueTemp=map2.get("1");
then you can iterate over this ArrayList to get those values ("2" and "3");
Try like this. //use list or set.. but set avoids duplicates
Map<String, Set<String>> map = new HashMap<>();
Set<String> list = new HashSet<>();
// add value to the map
Boolean b = map.containsKey(key);
if (b) {
map.get(key).addAll(list);
} else
map.put(key, list);
}
You can not add different values in same key in Map. Map is override the value in that key. You can do like this way.
Map<String, ArrayList<String>> map = new HashMap<String, ArrayList<String>>();
ArrayList<String> list=new ArrayList<String>();
list.add("2");
list.add("3");
map.put("1", list);
first add value in array list then put into map.
It is all because standard Map implementations in java stores only single pairs (oneKey, oneValue). The only way to store multiple values for a particular key in a java standard Map is to store "collection" as value, then you need to access this collection (from Map) by key, and then use this collection "value" as regular collection, in your example as ArrayList. So you do not put something directly by map.put (except from creating the empty collection), instead you take the whole collection by key and use this collection.
You need something like Multimap, for example:
public class Multimap<T,S> {
Map<T, ArrayList<S>> map2 = new HashMap<T, ArrayList<S>>();
public void add(T key, S value) {
ArrayList<T> currentValuesForGivenKey = get(key);
if (currentValuesForGivenKey == null) {
currentValuesForGivenKey = new ArrayList<T>();
map2.get(key, currentValuesForGivenKey);
}
currentValuesForGivenKey.add(value);
}
public ArrayList<S> get(T key) {
ArrayList<String> currentValuesForGivenKey = map2.get(key);
if (currentValuesForGivenKey == null) {
currentValuesForGivenKey = new ArrayList<S>();
map2.get(key, currentValuesForGivenKey);
}
return currentValuesForGivenKey;
}
}
then you can use it like this:
Multimap<String,String> map2 = new Multimap<String,String>();
map2.add("1","2");
map2.add("1","3");
map2.add("1","4");
for (String value: map2.get("1")) {
System.out.println(value);
}
will print:
2
3
4
it gives error that says "incompatible types" and it can not be converted to ArrayList and it says the error is at the value part of the line.
because, it won't automatically convert to ArrayList.
You should add both the values to list and then put that list in map.

What is difference between null and empty list?

List<Map<String, Object>> pcList = null;
Map<String, Object> pcMap = new HashMap<String, Object>();
ComputerConfigurations tempPC = null;
if (historyList != null) {
Iterator<ComputerConfigurations> iterator = historyList.iterator();
while (iterator.hasNext()) {
tempPC = (ComputerConfigurations) iterator.next();
pcMap.put(tempPC.getEnvironment(), tempPC);
pcList.add((Map<String, Object>) pcMap);
}
}
I am getting null pointer exception on pcList.add((Map<String, Object>)pcMap); line. [Servlet Error]-: java.lang.NullPointerException . Any suggestion ?
In Java, collections won't magically spring into existence just by adding something to them. You have to initialize pcList by creating an empty collection first:
List<Map<String, Object>> pcList = new ArrayList<>();
An empty collection isn't the same as null. An empty collection is actually a collection, but there aren't any elements in it yet. null means no collection exists at all.
Note that an object can't be of type List, because that's an interface; therefore, you have to tell Java what kind of List you really want (such as an ArrayList, as I've shown above, or a LinkedList, or some other class that implements List).
You're not initialising pcList at any point. Try this:
final List<Map<String, Object>> pcList = new LinkedList<>();
Map<String, Object> pcMap = new HashMap<String, Object>();
ComputerConfigurations tempPC = null;
if (historyList != null) {
Iterator<ComputerConfigurations> iterator = historyList.iterator();
while (iterator.hasNext()) {
tempPC = (ComputerConfigurations) iterator.next();
pcMap.put(tempPC.getEnvironment(), tempPC);
pcList.add((Map<String, Object>) pcMap);
}
}
Here is an example based answer. In this example below pcList is just initialized and is pointed to null(java do this for you, if it's a static or class member) since there are no empty list or values assigned to it.
List<Map<String, Object>> pcList;
Right now, pcList is assigned a new empty ArrayList. It does not have any values yet, but all positions in the list are empty and this pcList with the datatype ArrayList is pointed towards this new empty ArrayList.
List<Map<String, Object>> pcList = new ArrayList<>();
If an Object reference has been declared but not instantiated, its value is null.
List<Map<String, Object>> pcList = new ArrayList<Map<String, Object>>();
Map<String, Object> pcMap = new HashMap<String, Object>();
ComputerConfigurations tempPC = null;
if (historyList != null) {
Iterator<ComputerConfigurations> iterator = historyList.iterator();
while (iterator.hasNext()) {
tempPC = (ComputerConfigurations) iterator.next();
pcMap.put(tempPC.getEnvironment(), tempPC);
pcList.add((Map<String, Object>) pcMap);
}
}

Looping through a List<Map<Integer, Map<Long, Integer>>> in Java

As my title suggests, I'm struggling with looping through the data structure given.
I have a List of Maps which contain an Integer key and a Map value which contains a Long and an Integer.
How can I loop through the list, then map, then map to be able to access all of the required fields?
Thanks.
EDIT:
In response to the comments, the looping through the list I'm fine with.
So step one is to loop through the list, so I'm then left with:
for (Map<Integer, Map<Long, Integer>> periodScores : request.getPeriodScoreMap()) {
...
}
It's what goes in there that confuses me.
Currently I have:
for (Map<Integer, Map<Long, Integer>> periodScores : request.getPeriodScoreMap()) {
while (periodScores.entrySet().iterator().hasNext()) {
Map<Integer, Map<Long, Integer>> opponentScores =
(Map<Integer, Map<Long, Integer>>) periodScores.entrySet().iterator().next();
}
}
And I'm struggling to get into that final Map of
its just matter of being careful and being able to differentiate between map and list iterations
here is just an example:
for ( Map<Integer, Map<Long, Integer>> level1 : list){
for(Map.Entry<Integer,Map<Long, Integer>> level2 : level1.entrySet() ){
for(Map.Entry<Long,Integer> level3 : level2.getValue().entryList(){
}
}
}
Try this ;)
List<Map<Integer, Map<Long, Integer>>> myList = new LinkedList<>();
for(Map<Integer,Map<Long,Integer>> myListMap: myList){
for(Entry<Integer, Map<Long,Integer> myListMapEntry : myListMap.entrySet()){
Integer myListMapEntryInt = myListMapEntry.getKey();
for(Entry<Long, Integer> myListMapEntryValue : myListMapEntry.getValue()){
Long myListMapEntryValueLong = myListMapEntryValue.getKey();
Integer myListMapEntryValueInteger = myListMapEntryValue.getValue();
}
}
}
If the list of Maps is : List>> list;
Then you can access each Integer in the innermost map as follows:
for(Map<Integer,Map<Long,Integer>> outerMap : list){
for(Integer innerMapKeys : outerMap.keySet()){
Map<Long,Integer> innerMap = outerMap.get(innerMapKeys);
for(Long key:innerMap.keySet()){
System.out.println(innerMap.get(key));
}
}
}

Java: Sorting a Map, Map<Long,Map<String, Data>> based on the inner map

I am new to java and is still in the learning phase.
I have a structure
Map<Long, Map<String, Data>> mapData
Data has 2 fields time and distance
and the Map has a time which is a Long field and map with Identifier and Data
the structure looks like this
{190001919 = {[1= [data1], 2=[data2], 3=[data3]},
190001920={[1=[data4], 2=[data5], 3=[data6]},
1900019121= {[1=[data7], 2=[data8], 3=[data9]}}
and then convert it into a map - Map<String,List<Data>> mpData with
idenifier as key and values as the values where there the identifier was the same.
like
{1= [data1,data4,data7], 2= [data2,data5,data8],3= [data3,data6,data9]}
Could some one please help me?
Update:
With the below code, I get
{1= [data7,data7,data7], 2= [data8,data8,data8],3= [data9,data9,data9]}
instead of
{1= [data1,data4,data7], 2= [data2,data5,data8],3= [data3,data6,data9]}
Code:
public static Map<Long, Map<String, Data>> listData;
public static Map<String, List<Data>> mapData;
public convertMapData(Map<Long, Map<String, Data>> array) {
listData = new HashMap();
listData = array;
mapData = new HashMap<>();
Iterator it = listData.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<Long, Map<String, Data>> pairs = (Map.Entry) it
.next();
Long keyValue = pairs.getKey();
Map inter = pairs.getValue();
Iterator it2 = inter.entrySet().iterator();
while (it2.hasNext()) {
Map.Entry<String, Data> pairs_2 = (Map.Entry) it2
.next();
String identifierK = pairs_2.getKey();
Data resultV = pairs_2.getValue();
if (!(mapData.containsKey(identifierK))) {
mapData.put(identifierK, new ArrayList<Data>());
}
mapData.get(identifierK).add(resultV);
}
}
}
Define Map<String,List<Data>> listData = new HashMap<String, List<Data>>();
Iterate over mapData's values (seems you don't use the keys of that map).
For every value of mapData, which again is a map, iterate over the entrySet, which gives you key (a String, lets call it K) and value (a Data object, lets call it V) of every entry.
Check if your listData already has a key like K (using containsKey()) and if not, add one, using listData.put(K, new ArrayList<Data>())
add V to the list that's stored for the key: listData.get(K).add(V)
That's all. As Rohit Jain commented, you'll not need a list around the listData map.
Try this:
public Map<String, List<Data>> convert(Map<Long, Map<String, Data>> array) {
Map<String, List<Data>> result = new HashMap<String, List<Data>>();
for (Map<String, Data> inter : array.values()) {
for (Map.Entry<String, Data> entry : inter.entrySet()) {
String k = entry.getKey();
String v = entry.getValue();
if (!result.containsKey(k)) {
result.put(k, new ArrayList<Data>());
}
result.get(k).add(v);
}
}
return result;
}

Categories