I have a LinkedHashMap which fills with data from db with loop "for" string by string and when I try to show the first or the last String, the method can show me only the last String in log. But in application listViewContent is filled fully. So I don't understand why I can't see any string that I want. I need to collect all strings I get from db and compare them in future.
How can I collect all strings and what method should I call to show the string I want to see?Unfortunately I can only retrieve one (and the last instead of the first) string.
Here is my example code :
protected void onCreate(Bundle saveInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
FirstMethod();
}
public FirstMethod() {
SecondMethod newMethod = .. // getting data from the second method
}
public SecondMethod() {
public void onResponseReceived(String result) {
try {
...
if (posts != null) {
for (WallPostItem post : posts) { // this loop
//create new map for a post
Map<String, Object> map = new LinkedHashMap<String, Object>();
map.put(ATTRIBUTE_NAME_TEXT, post.text);
PictureItem postPicture = new PictureItem();
map.put(ATTRIBUTE_NAME_IMAGE, postPicture);
map.put(ATTRIBUTE_NAME_DATE, post.date);
sAdapter.notifyDataSetChanged();
};
};
...
List<Map.Entry<String, Object>> list = new ArrayList<Map.Entry<String, Object>>(GlobalMap.entrySet());
Map.Entry<String, Object> firstInsertedEntry = list.get(0);
Log.w("FirstEntryOfMap",""+firstInsertedEntry); // this log shows me the last string instead of the first
}
if (isRefresh) {
isRefresh = false;
lvSimple.setSelectionAfterHeaderView();
}
} catch (Exception e) {
Log.d("exceptions", "problem in get wall post task after post execute: " + e.toString());
}
}
You aren't putting your values into a List, you are putting them into a Map (that preserves key order). I would suggest you create a POJO class,
class MyAttribute {
final String postName;
final PictureItem postPicture;
final Date postDate;
public MyAttribute(String postName, PictureItem postPicture, Date postDate) {
this.postName = postName;
this.postPicture = postPicture;
this.postDate = postDate;
}
public String getPostName() {
return postName;
}
public Date getPostDate() {
return postDate;
}
public PictureItem getPostPicture() {
return postPicture;
}
}
Then you could create a
List<MyAttribute> myAttributes = new ArrayList<>();
Related
I am having a JSON data and I am converting that payload into a map object of nested. But it is overriding according to my logic.
I am having input json like this
{"mapping": {
"EVENT.alertMessage": "input.Message",
"EVENT.id": "input.id",
"EVENT.severity": "Functions.toString(\"P1\")",
"EVENT.eventTime": "input.eventTime",
"EVENT.eventType": "input.alertType",
"EVENT.geocoordinates.location": "Functions.toString(\"\")",
"EVENT.deviceName": "Functions.toString(\"\")",
"EVENT.visualInfo.imageUrl": "input.imageUrl",
"EVENT.deviceId": "input.cameraId",
"EVENT.geocoordinates.longitude": "Functions.toString(\"\")",
"EVENT.visualInfo.videoUrl": "input.videoUrl",
"EVENT.tenantCode": "Functions.toString(\"\")",
"EVENT.MAC": "input.cameraId",
"EVENT.DATE_TIME": "Functions.currentDate(\"yyyy-MM-dd HH:mm:ss\",\"UTC\")",
"EVENT.geocoordinates.latitude": "Functions.toString(\"\")"
}
}
Here from the above input JSON Keys I am iterating and forming map object.
ForEx:
INPUT:
{"mapping": {
"TEST.key1": "a",
"TEST.key2.key3": "b",
}
}
OUTPUT:
{
"TEST":{
"key1":a,
"key2":{
"key3":b
}
}
}
The code that I have written is
JSONObject json=new JSONObject(mappingData).getJSONObject("mapping");
Iterator<String> keys=new JSONObject(mappingData).getJSONObject("mapping").keys();
Map<String,Object> map = new HashMap<>();
while(keys.hasNext()) {
String val = keys.next();
String[] key=val.split("(?<!/)\\.");
Map<String, Object> lastKeyMap = null;
for(int i=0;i<key.length;i++)
{
if(i== 0 && key.length==1){
String outputVal=json.getString(val);
if(outputVal.contains("[]")){
outputVal=outputVal.replace("[]", "[i]");
}
//Matcher m = Pattern.compile("\\.([a-zA-Z0-9]{0,}\\/.[a-zA-Z0-9])|([a-zA-Z0-9]{0,}\\/.[a-zA-Z0-9])")
// .matcher(outputVal);
Matcher m = Pattern.compile("\\.([a-zA-Z0-9]{0,}\\/.[a-zA-Z0-9]{0,})")
.matcher(outputVal);
while (m.find()) {
outputVal=m.replaceAll("[`$1`]").replace("/", "");
}
if(key[i].contains("/"))
{
map.put("`"+key[i].replace("/", "")+"`",outputVal);
}
else{
map.put(key[i],outputVal);
}
}
else if(i== 0 && key.length>1){
if(map.containsKey(key[i])){
lastKeyMap = (Map<String, Object>) map.get(key[i]);
}else{
if(key[i].contains("/"))
{
lastKeyMap = new HashMap<String,Object>();
map.put("`"+key[i].replace("/", "")+"`",lastKeyMap);
}
else{
lastKeyMap = new HashMap<String,Object>();
map.put(key[i],lastKeyMap);
}
}
}else if(i== key.length-1 ){
String outputVal=json.getString(val);
if(outputVal.contains("[]")){
outputVal=outputVal.replace("[]", "[i]");
}
//Matcher m = Pattern.compile("\\.([a-zA-Z0-9]{0,}\\/.[a-zA-Z0-9])|([a-zA-Z0-9]{0,}\\/.[a-zA-Z0-9])")
// .matcher(outputVal);
Matcher m = Pattern.compile("\\.([a-zA-Z0-9]{0,}\\/.[a-zA-Z0-9]{0,})")
.matcher(outputVal);
while (m.find()) {
outputVal=m.replaceAll("[`$1`]").replace("/", "");
}
if(key[i].contains("/"))
{
lastKeyMap.put("`"+key[i].replace("/", "")+"`", outputVal);
}
else{
lastKeyMap.put(key[i], outputVal);
}
}else{
Map<String,Object> objMap = new HashMap<>();
if(key[i].contains("/"))
{
lastKeyMap.put("`"+key[i].replace("/", "")+"`", objMap);
lastKeyMap = objMap;
}
else{
lastKeyMap.put(key[i], objMap);
lastKeyMap = objMap;
}
}
}
}
The output I am getting is :
{EVENT={severity=Functions.toString("P1"), alertMessage=input.alertMessage, id=input.id, eventTime=input.eventTime, visualInfo={videoUrl=input.videoUrl}, eventType=input.alertType, tenantCode=Functions.toString(""), DATE_TIME=Functions.currentDate("yyyy-MM-dd HH:mm:ss","UTC"), geocoordinates={latitude=Functions.toString("")}, deviceName=Functions.toString(""), deviceId=input.cameraId, MAC=input.cameraId}}
But in the result EVENT.geocoordinates.longitude and EVENT.geocoordinates.longitude is skipped as the map is being overridden. Like that EVENT.visualInfo.imageUrl is also overridden by EVENT.visualInfo.videoUrl.So, how can I overcome this one and form a map or json with all the json keys by iterating without veing overriden.
The best approach is to create java class according to json schema:
public class Test {
#SerializedName("mapping")
public Mapping mapping;
static public class Mapping {
#SerializedName("EVENT.alertMessage")
public String alertMessage;
#SerializedName("EVENT.id")
public String id;
#SerializedName("EVENT.severity")
public String severity;
#SerializedName("EVENT.eventTime")
public String eventTime;
#SerializedName("EVENT.eventType")
public String eventType;
#SerializedName("EVENT.geocoordinates.location")
public String location;
#SerializedName("EVENT.deviceName")
public String deviceName;
#SerializedName("EVENT.visualInfo.imageUrl")
public String imageUrl;
#SerializedName("EVENT.deviceId")
public String deviceId;
#SerializedName("EVENT.geocoordinates.longitude")
public String longitude;
#SerializedName("EVENT.visualInfo.videoUrl")
public String videoUrl;
#SerializedName("EVENT.tenantCode")
public String tenantCode;
#SerializedName("EVENT.MAC")
public String mac;
#SerializedName("EVENT.DATE_TIME")
public String dateTime;
#SerializedName("EVENT.geocoordinates.latitude")
public String latitude;
}
}
And then parse it with google gson library
Test test = new Gson().fromJson("jsonString", Test.class);
Working with your own java object is much easier than with JSONObject
My current dependency for gson in gradle file:
implementation("com.google.code.gson:gson:2.8.6")
I have a method for get a List of users by its uid:
public void getNeededUsers(List<String> uidList, UsersListCallback usersListCallback) {
CollectionReference users = db.collection(Consts.USERS_DB);
for (String uid: uidList) {
users.whereEqualTo(Consts.UID, uid).get()
.addOnCompleteListener(task -> {
List<FsUser> fsUserList = new ArrayList<>();
for (DocumentSnapshot snapshot : task.getResult().getDocuments()) {
fsUserList.add(snapshot.toObject(FsUser.class));
}
usersListCallback.getUsers(fsUserList);
});
}
}
But it seems that this method doesn`t work properly. When I try to iterate through the List of users in another method, I receive users one by one from callback, instead of getting all, so they are duplicated in my list.
Here is a code of another method:
public void createUserChats(UserChatListCallback userChatListCallback) {
final List<UserChat> userChatList = new ArrayList<>();
getChatAndUidList((chatList, uidList) -> {
getRtUsersAndMessages(uidList, (rtUserList, messageList) -> {
getNeededUsers(uidList, userList -> {
if (!userList.isEmpty()) {
for (int i = 0; i < userList.size(); i++) {
String name = userList.get(i).getName();
String image = userList.get(i).getImage();
String userId = userList.get(i).getUid();
long timeStamp = chatList.get(i).getTimeStamp();
boolean seen = chatList.get(i).getSeen();
String online = rtUserList.get(i).getOnline();
String message = messageList.get(i).getMessage();
long messageTimestamp = messageList.get(i).getTime();
userChatList.add(new UserChat(name, image, timeStamp, seen, userId, online,
message, messageTimestamp));
}
}
userChatListCallback.getUserChatList(userChatList);
});
});
});
}
To get a list of users, please use the following code:
List<Task<DocumentSnapshot>> tasks = new ArrayList<>();
for (String uid: uidList) {
Task<DocumentSnapshot> documentSnapshotTask = users.whereEqualTo(Consts.UID, uid).get();
tasks.add(documentSnapshotTas);
}
Tasks.whenAllSuccess(tasks).addOnSuccessListener(new OnSuccessListener<List<Object>>() {
#Override
public void onSuccess(List<Object> list) {
//Do what you need to do with your users list
for (Object object : list) {
FsUser fsUser = ((DocumentSnapshot) object).toObject(TeacherPojo.class);
Log.d("TAG", fsUser.getName());
}
}
});
The problem is this adapter is giving the error although i have pass the Object array to it.(Read the methods belows then you will find what i want to know from you guys)
This method declares a List of private class objects. Then return that list of object to onPostExecute method.
private class DownloadXmlTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
try {
return loadXmlFromNetwork(urls[0]);
} catch (IOException e) {
return "I/O exception ae hy";
} catch (XmlPullParserException e) {
return "XML pull parser ke exception ae hy";
}
}
#Override
protected void onPostExecute(List<StackOverflowXmlParser.Entry> result) {
//Log.d(TAG,result.toString());
ArrayAdapter<String> adapter;
adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,result);
setListAdapter(adapter);
}
private Object loadXmlFromNetwork(String urlString) throws XmlPullParserException, IOException {
InputStream stream = null;
// Instantiate the parser
StackOverflowXmlParser stackOverflowXmlParser = new StackOverflowXmlParser();
List<StackOverflowXmlParser.Entry> entries = null;
String title = null;
String url = null;
String summary = null;
try {
stream = downloadUrl(urlString);
entries = stackOverflowXmlParser.parse(stream);
} finally {
if (stream != null) {
stream.close();
}
}
for (StackOverflowXmlParser.Entry entry : entries)
{
Log.d(TAG, entry.link + " /" + entry.title);
}
return entries;
}
I think it should be onPostExecute(List<StackOverflowXmlParser.Entry> result)
And you AsyncTask should be
extends AsyncTask<smth, smth, List<StackOverflowXmlParser.Entry> >
ArrayAdapter<String> requires that you provide it a String[] or a List<String>. You are trying to pass in Object[], which is neither String[] nor List<String>. And, it would appear that you are really trying to populate the ListView with a list of StackOverflowXmlParser.Entry objects, which are not String objects.
My guess is that the right answer is for you to create an ArrayAdapter<StackOverflowXmlParser.Entry> instead of an ArrayAdapter<String>.
Regardless, you need to ensure that the data type in your declaration (String in ArrayAdapter<String>) matches the data type in your constructor parameter that supplies the data to be adapted.
I have a json parse like this
public class SecondFragment extends Fragment implements OnClickListener {
// URL to get contacts JSON
private static String contestUrl = "http://api.apps.com/contest";
// JSON Node names
private static final String TAG_ITEM_ID = "id";
private static final String TAG_URL = "url";
private static final String TAG_START_DATE = "start_date";
private static final String TAG_END_DATE = "end_date";
// contacts JSONArray
JSONArray foods = null;
// Hashmap for ListView
ArrayList<HashMap<String, String>> foodslist;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
foodslist = new ArrayList<HashMap<String, String>>();
// Calling async task to get json
new GetContacts().execute();
}
/**
* Async task class to get json by making HTTP call
* */
private class GetContacts extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... arg0) {
// Creating service handler class instance
ServiceHandler sh = new ServiceHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(contestUrl, ServiceHandler.GET);
Log.d("Response: ", "> " + jsonStr);
if (jsonStr != null) {
try {
foods = new JSONArray(jsonStr);
// looping through All Contacts
for (int i = 0; i < foods.length(); i++) {
JSONObject c = foods.getJSONObject(i);
String id = c.getString(TAG_ITEM_ID);
String name = c.getString(TAG_URL);
String email = c.getString(TAG_START_DATE);
String address = c.getString(TAG_END_DATE);
// tmp hashmap for single contact
HashMap<String, String> contact = new HashMap<String, String>();
// adding each child node to HashMap key => value
contact.put(TAG_ITEM_ID, id);
contact.put(TAG_URL, name);
contact.put(TAG_START_DATE, email);
contact.put(TAG_END_DATE, address);
String start_date = (String)contact.get(TAG_ITEM_ID);
// adding contact to contact list
foodslist.add(contact);
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
return null;
}
}
}
I have two function, onCreate and GetContacts. In the end of onCreate it call GetContacts and call this json.
My question is, how can I got the Hashmap value on GetContacts so I can use it on onCreate
So far, I got this to get the value of Hashmap
String start_date = (String)contact.get(TAG_ITEM_ID);
But, its only works on GetContacts.
Anyone can help me?
Thanks Before
There are couple of ways:
Way-1:
Create instance variable (class-level) of HashMap contact and then you can use it anywhere within class inclusing onCreate and getContacts method.
package stackoverflow.q_25034927;
import java.util.HashMap;
import java.util.Map;
public class PassVariable {
private static Map<String, String> contact = new HashMap<String, String>();
public void onCreate() {
//populate contact object as per your logic
getContacts();
}
private void getContacts() {
//Use contact object directly which was pre-populby onCreate method.
}
}
Way-2:
Pass map to the getContacts() method:
package stackoverflow.q_25034927;
import java.util.HashMap;
import java.util.Map;
public class PassVariable {
public void onCreate() {
final Map<String, String> contact = new HashMap<String, String>();
//populate contact object as per your logic.
getContacts(contact);
}
private void getContacts(Map<String, String> contact) {
//Use contact object which is passed as argument.
}
}
On other side, please use cameCasing while naming Java methods or variables. GetContacts is not right, make it getContacts.
For email and address fields, using TAG_START_DATE and TAG_END_DATE is no fun. :-)
String email = c.getString(TAG_START_DATE);
String address = c.getString(TAG_END_DATE);
To answer about #3 below, variable s is not accessible in NotInner class:
package com.test;
public class Test {
static String s = "";
}
class NotInner {
public static void main(String[] args) {
System.out.println(s); //Compilation error: s cannot be resolved to a variable
}
}
You have
List<Map<String,String>> foodslist = ...;
which is filled in the loop.
To get at individual values, iterate:
for( Map<String,String> item: foodslist ){
String id = item.get(TAG_ITEM_ID);
String name = item.get(TAG_URL);
String email = item.get(TAG_START_DATE);
String address = item.get(TAG_END_DATE);
}
Or you write a method for the class where you keep foodslist:
String getAttr( int i, String tag ){
return foodslist.get(i).get(tag);
}
and you can call
String id = xxx.getAttr( i, TAG_ITEM_ID );
So return the data ...
public List<Map<String, String>> getContacts() {
if (foodslist != null && foodslist.isEmpty()) {
return foodslist;
}
foodslist = new ArrayList<Map<String, String>>();
try {
foods = new JSONArray(jsonStr);
// looping through All Contacts
for (int i = 0; i < foods.length(); i++) {
JSONObject c = foods.getJSONObject(i);
String id = c.getString(TAG_ITEM_ID);
String name = c.getString(TAG_URL);
String email = c.getString(TAG_START_DATE);
String address = c.getString(TAG_END_DATE);
// tmp hashmap for single contact
HashMap<String, String> contact = new HashMap<String, String>();
// adding each child node to HashMap key => value
contact.put(TAG_ITEM_ID, id);
contact.put(TAG_URL, name);
contact.put(TAG_START_DATE, email);
contact.put(TAG_END_DATE, address);
// adding contact to contact list
foodslist.add(contact);
}
return foodslist;
}
Though I'm not sure why that variable is called foodslist if it's supposed to contain contacts.
I'm new in coding and I have a problem to understand something. I follow the example form Parse.com Doc and wrote this.
public void getData() {
ParseQuery<ParseObject> query = ParseQuery.getQuery("ParseClass");
query.getInBackground("lxFzCTeOcl", new GetCallback<ParseObject>() {
public void done(ParseObject parseObject, ParseException e) {
if (e == null) {
String object = parseObject.getString("value");
int object_value = Integer.parseInt(obiect);
} else {
Log.d("score", "Error: " + e.getMessage());
}
}
});
}
I understand this like:
I send query to server
get obiect with "lxFzCTeOcl" id
if there is no exception I create String object which takes string
form "value" column.
convert String to int
My question is: How can I use object_value for example to make a chart or put it into a table?
Here we will add the array list to your code and start to store an object inside the array every time we call the getData method in your class.
private ArrayList<Integer> dataArray;
public void getData() {
ParseQuery<ParseObject> query = ParseQuery.getQuery("ParseClass");
query.getInBackground("lxFzCTeOcl", new GetCallback<ParseObject>() {
public void done(ParseObject parseObject, ParseException e) {
if (e == null) {
String object = parseObject.getString("value");
Integer objectValue = Integer.parseInt(obiect);
if(dataArray==null)
dataArray = new ArrayList<Integer>();
dataArray.add(objectValue);
} else {
Log.d("score", "Error: " + e.getMessage());
}
}
});
}
And here I'm just adding a simple example of how to create a simple pie chart using our array list (note that I used the lib AChartEngine http://www.achartengine.org/):
private static int[] COLORS = new int[] { Color.GREEN, Color.BLUE,Color.MAGENTA, Color.CYAN };
private GraphicalView createPieChart(ArrayList<Integer> data){
GraphicalView chartView;
CategorySeries series = new CategorySeries("PIE");
for (int i = 0; i < VALUES.length; i++) {
series.add(i, data.get(i));
SimpleSeriesRenderer renderer = new SimpleSeriesRenderer();
renderer.setColor(COLORS[(series.getItemCount() - 1) % COLORS.length]);
mRenderer.addSeriesRenderer(renderer);
}
chartView = ChartFactory.getPieChartView(this, series, new DefaultRenderer());
chartView.repaint();
return chartView;
}
Now you can add this GraphicalView to your view.
The returned object is much like a map, with key/value pairs. In your example, the key is "value", which makes it a little confusing, but it would be like this if you wanted all fields:
for (Field field : myInstance.getClass().getDeclaredFields()) {
String name = field.getName();
value = field.get(myInstance).toString();
map.put(name, value);
}