First, sorry for my poor English.
Second, my problem.
I trying convert to JSON and back this structure:
class Revision{
private String auth;
private HashMap<String, List<HashMap<String, Object>>> rev;
public String getAuth(){
return auth;
}
public HashMap<String, List<HashMap<String, Object>>> getRev(){
return rev;
}
public void setAuth(String auth){
this.auth = auth;
}
public void setRev(HashMap<String, List<HashMap<String, Object>>> rev){
this.rev = (HashMap<String, List<HashMap<String, Object>>>) rev.clone();
}
public String toString(){
return "Auth: " + auth + ", rev: " + rev;
}
}
I do it with this code:
public static void main (String[] argc){
Gson gson = new Gson();
Revision revision = new Revision();
HashMap<String, List<HashMap<String, Object>>> HM = new HashMap<String, List<HashMap<String, Object>>>();
List<HashMap<String, Object>> list = new ArrayList<HashMap<String, Object>>();
HashMap<String, Object> HMin = new HashMap<String, Object>();
HMin.put("id", 12);
HMin.put("type", "toster");
list.add(HMin);
HM.put("mark", list);
revision.setRev(HM);
revision.setAuth("ololo");
String json = gson.toJson(revision);
Revision test = new Gson().fromJson(json, Revision.class);
System.out.println(json);
System.out.println(revision);
System.out.println(test);
}
In finally I get this result:
{"auth":"ololo","rev":{"mark":[{"id":12,"type":"toster"}]}}
Auth: ololo, rev: {mark=[{id=12, type=toster}]}
Auth: ololo, rev: {mark=[{id=java.lang.Object#1c672d0, type=java.lang.Object#19bd03e}]}
As you can see, after convertation, Object-type parameters incorrect.
Please, can you tell me, how I can fix this trouble?
Thank you in advance!
Try this out and see if it is working? Yeah, I know you want to support Object type, but this is just for try sake.
Gson gson = new Gson();
Revision revision = new Revision();
HashMap<String, List<HashMap<String, String>>> HM = new HashMap<String, List<HashMap<String, String>>>();
List<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();
HashMap<String, String> HMin = new HashMap<String, String>();
HMin.put("id", "12");
HMin.put("type", "toster");
list.add(HMin);
HM.put("mark", list);
revision.setRev(HM);
revision.setAuth("ololo");
String json = gson.toJson(revision);
Revision test = new Gson().fromJson(json, Revision.class);
System.out.println(json);
System.out.println(revision);
System.out.println(test);
[Edited]
Now try this snippet directly, with a respective change in Revision class.
Revision test = new Gson().fromJson("{\"auth\":\"ololo\",\"rev\":{\"mark\":[{\"id\":12,\"type\":13}]}}", Revision.class);
System.out.println(test);
Change this in Revision class to this,
HashMap<String, List<HashMap<String, Integer>>> HM = new HashMap<String, List<HashMap<String, Integer>>>();
This is to make sure that its working good with specific type. If it does, we will be sure that it can't work with Obejct type somehow. Then you can file a bug there, for their good. And for the time being you can switch to some other API, if you like to. You can find few options here.
Related
Hi I'm trying to create yaml file using java and snakeyaml but i did basic coding on it and wanted to improvise on the creation of hash maps and array list with class objects anyone can help in refactoring this code as I'm new to java.I want help in specifically creating classes for the redundant objects created in createmap function
Sample Code
package com.yaml.writer;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class JavaToYamlWithOptions {
public static void main(String[] args) {
Map<String,Object> map = createMap();
DumperOptions options = new DumperOptions();
options.setIndent(2);
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
options.setPrettyFlow(true);
Yaml yaml = new Yaml(options);
String output = yaml.dump(map);
System.out.println(output);
}
private static Map<String,Object> createMap() {
Map<String,Object> env = new HashMap<>();
Map<String,String> rpath = new HashMap<>();
Map<String,String> rtab = new HashMap<>();
List<Map<String,String>> rlist = new ArrayList<>();
rpath.put("path","hdfs");
rtab.put("tabname","tbl");
rlist.add(rpath);
rlist.add(rtab);
Map<String,List<Map<String,String>>> parq = new HashMap<>();
parq.put("parquet",rlist);
List<Map<String,List<Map<String,String>>>> readlst = new ArrayList<>();
readlst.add(parq);
Map<String,List<Map<String,List<Map<String,String>>>>> readmap = new HashMap<>();
readmap.put("read", readlst);
Map<String,String> coltrans = new HashMap<>();
Map<String,String> colsec = new HashMap<>();
List<Map<String,String>> collist = new ArrayList<>();
coltrans.put("coltrans","colxx");
colsec.put("coal","false");
collist.add(coltrans);
collist.add(colsec);
Map<String,List<Map<String,String>>> trans = new HashMap<>();
trans.put("transform",collist);
List<Map<String,List<Map<String,String>>>> trlist = new ArrayList<>();
trlist.add(trans);
Map<String,List<Map<String,List<Map<String,String>>>>> trmap = new HashMap<>();
trmap.put("transform", trlist);
env.put("environment" ,"kubernetes");
Map<String,String> wpath = new HashMap<>();
List<Map<String,String>> wlist = new ArrayList<>();
wpath.put("path","whdfs");
wlist.add(wpath);
Map<String,List<Map<String,String>>> wparq = new HashMap<>();
wparq.put("parquet",wlist);
List<Map<String,List<Map<String,String>>>> wrlst = new ArrayList<>();
wrlst.add(wparq);
Map<String,List<Map<String,List<Map<String,String>>>>> wmap = new HashMap<>();
wmap.put("write", wrlst);
Map<String,Object> action = new HashMap<>();
trmap.putAll(wmap);
readmap.putAll(trmap);
action.put("action1",readmap);
Map<String,Object> actions = new HashMap<>();
actions.put("action",action);
env.putAll(actions);
return env;
}
}
expected output
environment: "kubernetes"
action:
action1:
transform:
- transform:
- colTrans: colxx
- coal: false
read:
- parquet:
- path: "hdfs"
- tabname: "tbl"
write:
- parquet:
- path: "whdfs"
I have a hashmap of string
HashMap<String, String> hashMap = new HashMap<>();
hashMap.put("name", name);
hashMap.put("number", number);
hashMap.put("profileImage", image);
and a List of Hashmap
List<HashMap<String, String>> recents = new ArrayList<>();
recents.add(hashMap);
Now I have to save this list
I have tried using https://github.com/pilgr/Paper to save this List
Paper.book().write("recents", recents);
but i can't get the list back
List<HashMap<String, String>> list = Paper.book().read("recents");
HashMap<String,String> hashMap = list.get(0);
String name = hashMap.get("name");
String number = hashMap.get("number");
String image = hashMap.get("profileImage");
Uses of the code
actually I'm passing this list to recycelerViewAdapeter and from there in OnBindViewHolder() I'm getting all the Hashmap values and displaying it to user
Saving Data Code
Paper.init(this);
List<HashMap<String, String>> recents = new ArrayList<>();
HashMap<String, String> hashMap = new HashMap<>();
hashMap.put("name", name);
hashMap.put("number", number);
hashMap.put("profileImage", image);
recents.add(hashMap);
Paper.book().write("recents", contacts);
Receiving Data Code
Paper.init(requireActivity());
recyclerView = view.findViewById(R.id.recyclerView);
List<HashMap<String, String>> list = Paper.book().read("recents");
Adapter = new Adapter(requireActivity(), list);
recyclerView.setAdapter(Adapter);
You can use Gson and SharedPreferences to do the same.
implementation 'com.google.code.gson:gson:2.8.9'
Example:
private SharedPreferences sp;
private HashMap<String, Boolean> favs;
....
....
public void addFavourite(String wall_name) {
favs = getFavourites();
favs.put(wall_name, true);
setFavourties();
}
public void removeFav(String wall_name) {
favs = getFavourites();
favs.put(wall_name, false);
setFavourties();
}
private void setFavourties() {
SharedPreferences.Editor pe = sp.edit();
Gson gson = new Gson();
String j = gson.toJson(favs);
pe.putString("Favourites", j);
pe.apply();
}
public HashMap<String, Boolean> getFavourites() {
Gson gson = new Gson();
String j = sp.getString("Favourites", null);
if (j != null) {
Type stringBooleanMap = new TypeToken<HashMap<String, Boolean>>() {
}.getType();
return gson.fromJson(j, stringBooleanMap);
} else {
return new HashMap<>();
}
}
First of all let me describe the scenario.
Step 1. I have to read from a file, line by line. The file is a .json and each line has the following format:
{
"schema":{Several keys that are to be deleted},
"payload":{"key1":20001,"key2":"aaaa","key3":"bbbb","key4":"USD","key5":"100"}
}
Step 2. Delete schema object and end up with (added more examples for the sake of the next steps):
{"key1":20001,"key2":"aaaa","key3":"bbbb","key4":"USD","key5":"100"}
{"key1":20001,"key2":"aaaa","key3":"bbbb","key4":"US","key5":"90"}
{"key1":2002,"key2":"cccc","key3":"hhhh","key4":"CN","key5":"80"}
Step 3. Split these values into key and value by making them json in memory and use the strings as keys and values with map
{"key1":20001,"key2":"aaaa","key3":"bbbb"} = {"key4":"USD","key5":"100"}
{"key1":20001,"key2":"aaaa","key3":"bbbb"} = {"key4":"US","key5":"90"}
{"key1":2002,"key2":"cccc","key3":"hhhh"} = {"key4":"CN","key5":"80"}
Step 4, and the one I can't work out due to my lack of knowledge in Pcollections. I need to grab all the lines read and do a GroupByKey so that it would end up like:
{"key1":20001,"key2":"aaaa","key3":"bbbb"} = [
{"key4":"USD","key5":"100"},
{"key4":"US","key5":"90"} ]
{"key1":2002,"key2":"cccc","key3":"hhhh"} = {"key4":"CN","key5":"80"}
Righ now my code looks like this:
static void runSimplePipeline(PipelineOptionsCustom options) {
Pipeline p = Pipeline.create(options);
p.apply("ReadLines", TextIO.read().from(options.getInputFile()))
.apply("TransformData", ParDo.of(new DoFn<String, String>() {
#ProcessElement
public void processElement(ProcessContext c) {
Gson gson = new GsonBuilder().create();
ObjectMapper oMapper = new ObjectMapper();
JSONObject obj_key = new JSONObject();
JSONObject obj_value = new JSONObject();
List<String> listMainKeys = Arrays.asList(new String[]{"Key1", "Key2", "Key3"});
HashMap<String, Object> parsedMap = gson.fromJson(c.element().toString(), HashMap.class);
parsedMap.remove("schema");
Map<String, String> map = oMapper.convertValue(parsedMap.get("payload"), Map.class);
for (Map.Entry<String,String> entry : map.entrySet()) {
if (listMainKeys.contains(entry.getKey())) {
obj_key.put(entry.getKey(),entry.getValue());
} else {
obj_value.put(entry.getKey(),entry.getValue());
}
}
KV objectKV = KV.of(obj_key.toJSONString(), obj_value.toJSONString());
System.out.print(obj_key.toString() + " : " + obj_value.toString() +"\n");
}
})); <------- RIGHT HERE
p.run().waitUntilFinish();
}
Now the obvious part is that on where it says "RIGHT HERE" I should have another apply with CountByKey however that requires a full PCollection and that's what I do not really understand.
Here's the code, thanks to Guillem Xercavins's linked Github:
static void runSimplePipeline(PipelineOptionsCustom options) {
Pipeline p = Pipeline.create(options);
PCollection<Void> results = p.apply("ReadLines", TextIO.read().from(options.getInputFile()))
.apply("TransformData", ParDo.of(new DoFn<String, KV<String, String>>() {
#ProcessElement
public void processElement(ProcessContext c) {
Gson gson = new GsonBuilder().create();
ObjectMapper oMapper = new ObjectMapper();
JSONObject obj_key = new JSONObject();
JSONObject obj_value = new JSONObject();
List<String> listMainKeys = Arrays
.asList(new String[] { "EBELN", "AEDAT", "BATXT", "EKOTX", "Land1", "WAERS" });
HashMap<String, Object> parsedMap = gson.fromJson(c.element().toString(), HashMap.class);
parsedMap.remove("schema");
Map<String, String> map = oMapper.convertValue(parsedMap.get("payload"), Map.class);
for (Map.Entry<String, String> entry : map.entrySet()) {
if (listMainKeys.contains(entry.getKey())) {
obj_key.put(entry.getKey(), entry.getValue());
} else {
obj_value.put(entry.getKey(), entry.getValue());
}
}
KV objectKV = KV.of(obj_key.toJSONString(), obj_value.toJSONString());
c.output(objectKV);
}
})).apply("Group By Key", GroupByKey.<String, String>create())
.apply("Continue Processing", ParDo.of(new DoFn<KV<String, Iterable<String>>, Void>() {
#ProcessElement
public void processElement(ProcessContext c) {
System.out.print(c.element());
}
}));
p.run().waitUntilFinish();
}
I am trying to insert a row to BigQuery using java.
The entity I was inserting has a field which is double nested.
Generating the entity suitable for BigQuery:
ObjectMapper mapper = new ObjectMapper();
String barcodeDetailsJSON = order.getBarcodeDetailsJSON();
List<StateForBQ> stateForBQList = new ArrayList<StateForBQ>();
for (State state : order.getStates()) {
StateForBQ stateForBQ = new StateForBQ(state);
stateForBQ.setSetOn(new Date(stateForBQ.getSetOn().getTime()/1000));
stateForBQList.add(stateForBQ);
}
List<BarcodeDetailForBQ> barcodeDetailForBQList = getBarcodeDetailsFromBarcodeDetailsJSON(barcodeDetailsJSON, order.getIsGrouped());
Without the following, state is getting set as null. (State is nested entity)
List<Map<String, Object>> stateMap =
mapper.convertValue(stateForBQList, new TypeReference<List<Map<String, Object>>>() {});
Without the following, barcodeDetails is getting set as null. (BarcodeDetails is double nested entity)
List<Map<String, Object>> barcodeMapList =
mapper.convertValue(barcodeDetailForBQList, new TypeReference<List<Map<String, Object>>>() {});
Without the follwing, productPriceDetails, productDetails, cgst, sgst are getting set as null
for (Map<String, Object> barcodeMap : barcodeMapList) {
barcodeMap.put("productPriceDetails", mapper.convertValue(barcodeMap.get("productPriceDetails"), new TypeReference<Map<String, Object>>() {}));
barcodeMap.put("productDetails", mapper.convertValue(barcodeMap.get("productDetails"), new TypeReference<Map<String, Object>>() {}));
barcodeMap.put("cgst", mapper.convertValue(barcodeMap.get("cgst"), new TypeReference<Map<String, Object>>() {}));
barcodeMap.put("sgst", mapper.convertValue(barcodeMap.get("sgst"), new TypeReference<Map<String, Object>>() {}));
}
Preparing the rowcontent
Map<String, Object> rowContent = new HashMap<>();
rowContent.put("orderId", order.getOrderId());
rowContent.put("customerId", order.getCustomerId());
rowContent.put("barcodeDetails", barcodeMapList);
rowContent.put("states", stateMap);
Inserting to BigQuery
Gson gson = new Gson();
BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();
String datasetName = "Latest_Data";
String tableName= "ORDER_TEMP";
// [START bigquery_table_insert_rows]
TableId tableId = TableId.of(datasetName, tableName);
// Values of the row to insert
String barcodeDetailsJSON = order.getBarcodeDetailsJSON();
List<BarcodeDetailForBQ> barcodeDetailForBQList = new OrderForBQ().getBarcodeDetailsFromBarcodeDetailsJSON(barcodeDetailsJSON, order.getIsGrouped());
String recordsContentString = gson.toJson(rowContent);
InsertAllResponse response =
bigquery.insertAll(
InsertAllRequest.newBuilder(tableId)
.addRow(""+orderId, rowContent)
// More rows can be added in the same RPC by invoking .addRow() on the builder
.build());
if (response.hasErrors()) {
// If any of the insertions failed, this lets you inspect the errors
for (Entry<Long, List<BigQueryError>> entry : response.getInsertErrors().entrySet()) {
// inspect row error
}
}
Following is the response I am getting.
{
insertErrors: {
0: [
{
reason: "invalid",
location: "",
message: "Repeated record added outside of an array."
}
]
}
}
HashMap<String, HashMap<String, String>> hm = new HashMap<String, HashMap<String, String>>();
hm.put("Title1","Key1");
for(int i=0;i<2;i++) {
HashMap<String, String> hm1 = new HashMap<String, String>();
hm1.put("Key1","Value1");
}
if i have call Title1 that time they call another hashmap. i want
this type of output
hm<key,value(object hm1)>
hm<key,value)
first hashmap object call second hashmap key
If I correct undestand what you want, use following code
HashMap<String, HashMap<String, String>> hm = new HashMap<>();
HashMap<String, String> hm1 = new HashMap<>();
for(int i=0;i<2;i++) {
hm1.put("Key1","Value1");
}
hm.put("Title1", hm1); // save hm
...
HashMap<String, String> hm2 = hm.get("Title1");
String s = hm2.get("Key1"); // s = "Value1"
OR you can create new class
class HashKey {
private String title;
private String key;
...
// getters, setters, constructor, hashcode and equals
}
and just use HashMap < HashKey, String > hm, for example:
hm.put(new HashKey("Title1", "Key 1"), "Value");
...
String s = hm.get(new HashKey("Title1", "Key 1")); // Value
you can do something likewise,
HashMap<String,HashMap<String,String>> hm = new HashMap<String,HashMap<String,String>>();
HashMap<String,String> hm1 = new HashMap<String,String>();
hm1.put("subkey1","subvalue");
hm.put("Title1",hm1);
HashMap<String,String> newhm = hm.get("Title1");
import java.util.HashMap;
import java.util.Map;
public class MapInMap {
Map<String, Map<String, String>> standards =
new HashMap<String, Map<String, String>>();
void addValues() {
Map<String, String> studentA = new HashMap<String, String>();
studentA.put("A1", "49");
studentA.put("A2", "45");
studentA.put("A3", "43");
studentA.put("A4", "39");
standards.put("A", studentA);
Map<String, String> studentB = new HashMap<String, String>();
studentB.put("B1", "29");
studentB.put("B2", "25");
studentB.put("B3", "33");
studentB.put("B4", "29");
standards.put("B", studentB);
}
void disp() {
for (Map.Entry<String, Map<String, String>> entryL1 : standards
.entrySet()) {
System.out.println("Standard :" + entryL1.getKey());
for (Map.Entry<String, String> entryL2 : entryL1.getValue()
.entrySet()) {
System.out.println(entryL2.getKey() + "/" + entryL2.getValue());
}
}
}
public static void main(String args[]) {
MapInMap inMap = new MapInMap();
inMap.addValues();
inMap.disp();
}
}