Java JSON -Jackson- Nested Elements - java

My JSON string has nested values.
Something like
"[{"listed_count":1720,"status":{"retweet_count":78}}]"
I want the value of the retweet_count.
I'm using Jackson.
The code below outputs "{retweet_count=78}" and not 78. I'm wondering if I can get nested values the kind of way PHP does it i.e status->retweet_count. Thanks.
import java.io.IOException;
import java.util.List;
import java.util.Map;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
public class tests {
public static void main(String [] args) throws IOException{
ObjectMapper mapper = new ObjectMapper();
List <Map<String, Object>> fwers = mapper.readValue("[{\"listed_count\":1720,\"status\":{\"retweet_count\":78}}]]", new TypeReference<List <Map<String, Object>>>() {});
System.out.println(fwers.get(0).get("status"));
}
}

If you know the basic structure of the data you're retrieving, it makes sense to represent it properly. You get all sorts of niceties like type safety ;)
public static class TweetThingy {
public int listed_count;
public Status status;
public static class Status {
public int retweet_count;
}
}
List<TweetThingy> tt = mapper.readValue(..., new TypeReference<List<TweetThingy>>() {});
System.out.println(tt.get(0).status.retweet_count);

Try something like that. If you use JsonNode your life gonna be easier.
JsonNode node = mapper.readValue("[{\"listed_count\":1720,\"status\":{\"retweet_count\":78}}]]", JsonNode.class);
System.out.println(node.findValues("retweet_count").get(0).asInt());

You can probably do System.out.println(fwers.get(0).get("status").get("retweet_count"));
Edit 1:
Change
List <Map<String, Object>> fwers = mapper.readValue(..., new TypeReference<List <Map<String, Object>>>() {});
to
List<Map<String, Map<String, Object>>> fwers = mapper.readValue(..., new TypeReference<List<Map<String, Map<String, Object>>>>() {});
And then do System.out.println(fwers.get(0).get("status").get("retweet_count"));
You don't have a Map of pairs, you have a Map of <String, Map<String, Object>> pairs.
Edit 2:
Alright I get it. So you have a list of maps. And in the first map in the list, you have a kv pair where the value is an integer, and another kv pair where the value is another map. When you say you have a list of maps of maps it complains because the kv pair with the int value isn't a map (it's just an int). So you either have to make all of your kv pairs maps (change that int to a map) and then use my edits above. Or you can use your original code, but cast the Object to a Map when you know it is a Map.
So try this:
Map m = (Map) fwers.get(0).get("status");
System.out.println(m.get("retweet_count"));

Related

Find List Item in List of HashMaps

I have a List<Map<String, Object>> and want to find an item by its id and then return a property of that HashMap. Let me illustrate this with an example:
List<Map<String, Object>> test = new ArrayList<Map<String, Object>>();
var first = new HashMap<String, Object>();
first.put("Id", "4711");
first.put("State", "Ok");
var second = new HashMap<String, Object>();
second.put("Id", "4712");
second.put("State", "Not Ok");
test.add(first);
test.add(second);
How would I search the list of hashmaps where Id is 4712 and get its State?
I know I can do this by manually iterating over the list. However, I would prefer this to be done with streams.
As Joachim Sauer wrote in his comment, just because some aspect of the Java programming language is newer (and appears "cooler") doesn't mean it is better. As the saying goes:
The right tool for the right job.
Anyway, the below code produces the desired result from the input provided in your question.
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Test {
public static void main(String[] args) {
List<Map<String, Object>> test = new ArrayList<Map<String, Object>>();
var first = new HashMap<String, Object>();
first.put("Id", "4711");
first.put("State", "Ok");
var second = new HashMap<String, Object>();
second.put("Id", "4712");
second.put("State", "Not Ok");
test.add(first);
test.add(second);
Object val = test.stream() // Every element in stream has type Map<String, Object>
.filter(m -> "4712".equals(m.get("Id")))
.findFirst() // returns Optional<Map<String, Object>>
.get() // throws 'NoSuchElementException' if nothing found
.get("State"); // i.e. java.util.Map#get
System.out.println(val);
}
}
Running the above code displays:
Not Ok
You can use the get method and pass "4712" as key.
See Java documentation, https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html#get-java.lang.Object-

Java How to access hash map data held in an array

learning Java and have figured out how to store a hashmap in an array. But I can't figure out how to get to the stored data. Here is a simplified version of what I'm doing. I've got as far as displaying the specific array items, but how do I access the hash map stored in the array?
import java.util.*;
public class HelloWorld {
public static void main(String[] args) {
Map<String, String> custOrder = new HashMap<String, String>();
List ordersPlaced = new ArrayList();
custOrder.put("colour", "blue");
custOrder.put("manu", "bmw");
custOrder.put("body", "4x4");
ordersPlaced.add(custOrder);
custOrder = new HashMap();
custOrder.put("colour", "green");
custOrder.put("manu", "merc");
custOrder.put("body", "saloon");
ordersPlaced.add(custOrder);
System.out.println(ordersPlaced.get(0).toString());
}
}
Hope that makes sense. Thanks in advance
Neil
You're already accessing it.
In order to get the iterate on the map's items, you can:
ordersPlaced.get(0).forEach((key, value) -> {
System.out.println("Key is: " + key + ", Value is: " + value);
});
Or, earlier to Java 8, something like:
for (Map.Entry<String, String> entry : ordersPlaced.get(0).entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
}
Please note that you should avoid using raw type list. Instead, you should have:
List<Map<String, String>> ordersPlaced = new ArrayList<>();
And then:
Map<String, String> m = ordersPlaced.get(0);
You know it already.
You can get back the stored map by writing
Map<String, String> placedCustOrder = ordersPlaced.get(0);
And avoid using raw types while using List. Declare your list as
List<Map<String, String>> ordersPlaced = new ArrayList<>();
I would like to know how to access the colour of the data stored in the array at location 0
Since you got the map as I said in the line 1
Map<String, String> placedCustOrder = ordersPlaced.get(0);
String colorVal = placedCustOrder.get("colour");
I strongly suggest you to look through Map documentation before proceeding further.

I need to hold multiple int values in a Map

I need to create a book index method which can pair multiple values to one key
e.g
key - "Beck,Kent"
value - 27 23 76
is this possible?
the import ou.*; is the Open University library and should not affect anything.
import java.util.*;
import ou.*;
public class BookIndex
{
public Map<String, Integer> index()
{
Map<String, Integer> actual = new HashMap<>();
return actual;
}
Thanks
How about using an integer array instead of an Integer in Map<String, Integer>.
HashMap<String, Integer[]> anewMap = new HashMap<String, Integer[]>();
anewMap.put("Beck,Kent",new Integer[] { 27, 23, 76});
I would make and object to store instead of the Integer that holds the int values.
Map<String, YourObject> actual = new HashMap<>();
If you could be more specific about things I could show you what that class might look like. In your example you would use the KEY "Beck,Kent" to search for the values with the function get(), this is as much help as I can give currently

Computing the union of the keySets of two HashMaps in Java

I want to compute the union of the keys of two hashmaps. I wrote the following code (MWE below), but I
get UnsupportedOperationException. What would be a good of accomplishing this?
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class AddAll {
public static void main(String args[]){
Map<String, Integer> first = new HashMap<String, Integer>();
Map<String, Integer> second = new HashMap<String, Integer>();
first.put("First", 1);
second.put("Second", 2);
Set<String> one = first.keySet();
Set<String> two = second.keySet();
Set<String> union = one;
union.addAll(two);
System.out.println(union);
}
}
So, union is not a copy of one, it is one. It is first.keySet(). And first.keySet() isn't a copy of the keys of first, it's a view, and won't support adds, as documented in Map.keySet().
So you need to actually do a copy. The simplest way is probably to write
one = new HashSet<String>(first);
which uses the "copy constructor" of HashSet to do an actual copy, instead of just referring to the same object.
Remember the keySet is the actual data of the map, it's not a copy. If it let you call addAll there, you'd be dumping all those keys into the first map with no values! The HashMap purposely only allows you to add new mappings by using the put type methods of the actual map.
You want union to be an actual new set probably, not the backing data of the first hashmapL
Set<String> one = first.keySet();
Set<String> two = second.keySet();
Set<String> union = new HashSet<String>(one);
union.addAll(two);
Use below code instead
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class AddAll {
public static void main(String args[]){
Map<String, Integer> first = new HashMap<String, Integer>();
Map<String, Integer> second = new HashMap<String, Integer>();
Map<String, Integer> union = new HashMap<String, Integer>();
first.put("First", 1);
second.put("Second", 2);
union.putAll(first);
union.putAll(second);
System.out.println(union);
System.out.println(union.keySet());
}
}

How to do an array of hashmaps?

This is what I tried to do, but it gives me a warning:
HashMap<String, String>[] responseArray = new HashMap[games.size()];
Type safety: The expression of type HashMap[ ] needs unchecked conversion to conform to HashMap[ ]
What gives? It works. Just ignore it:
#SuppressWarnings("unchecked")
No, you cannot parameterize it. I'd however rather use a List<Map<K, V>> instead.
List<Map<String, String>> listOfMaps = new ArrayList<Map<String, String>>();
To learn more about collections and maps, have a look at this tutorial.
You can use something like this:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class testHashes {
public static void main(String args[]){
Map<String,String> myMap1 = new HashMap<String, String>();
List<Map<String , String>> myMap = new ArrayList<Map<String,String>>();
myMap1.put("URL", "Val0");
myMap1.put("CRC", "Vla1");
myMap1.put("SIZE", "Val2");
myMap1.put("PROGRESS", "Val3");
myMap.add(0,myMap1);
myMap.add(1,myMap1);
for (Map<String, String> map : myMap) {
System.out.println(map.get("URL"));
System.out.println(map.get("CRC"));
System.out.println(map.get("SIZE"));
System.out.println(map.get("PROGRESS"));
}
//System.out.println(myMap);
}
}
The Java Language Specification, section 15.10, states:
An array creation expression creates
an object that is a new array whose
elements are of the type specified by
the PrimitiveType or
ClassOrInterfaceType. It is a
compile-time error if the
ClassOrInterfaceType does not denote a
reifiable type (ยง4.7).
and
The rules above imply that the element
type in an array creation expression
cannot be a parameterized type, other
than an unbounded wildcard.
The closest you can do is use an unchecked cast, either from the raw type, as you have done, or from an unbounded wildcard:
HashMap<String, String>[] responseArray = (Map<String, String>[]) new HashMap<?,?>[games.size()];
Your version is clearly better :-)
You can't have an array of a generic type. Use List instead.
Java doesn't want you to make an array of HashMaps, but it will let you make an array of Objects. So, just write up a class declaration as a shell around your HashMap, and make an array of that class. This lets you store some extra data about the HashMaps if you so choose--which can be a benefit, given that you already have a somewhat complex data structure.
What this looks like:
private static someClass[] arr = new someClass[someNum];
and
public class someClass {
private static int dataFoo;
private static int dataBar;
private static HashMap<String, String> yourArray;
...
}
Regarding the #alchemist's answer, I added some modifications using only HashMap and ArrayList:
import java.util.ArrayList;
import java.util.HashMap;
public class ArrayOfHash {
public static void main(String[] args) {
HashMap<String,String> myMap = new HashMap<String, String>();
ArrayList<HashMap<String , String>> myArrayMap = new ArrayList<HashMap<String,String>>();
myMap.put("Key1", "Val0");
myMap.put("Key2", "Val1");
myMap.put("Key3", "Val2");
myMap.put("Key4", "Val3");
myArrayMap.add(myMap);
myArrayMap.add(myMap);
for (int i = 0; i < myArrayMap.size(); i++) {
System.out.println(myArrayMap.get(i).get("Key1") + ","
+ "" + myArrayMap.get(i).get("Key2") + ","
+ "" + myArrayMap.get(i).get("Key3") + ","
+ "" + myArrayMap.get(i).get("Key4"));
System.out.println(); // used as new blank line
}
}

Categories

Resources