Got invalid value from ArrayList<HashMap<String, String>> - java

I am getting invalid value in ListView. My code is below.
final ArrayList<HashMap<String, String>> placesListItems = new ArrayList<HashMap<String, String>>();
runOnUiThread(new Runnable() {
public void run() {
try {
HashMap<String, String> map = new HashMap<String, String>();
for (int i = 0; i < dealList.size(); i++) {
map.put(DealItem.DEAL_ID, dealList.get(i).deal_id);
map.put(DealItem.DEAL_NAME, dealList.get(i).deal_name);
System.out.println("DEAL NAME = "+dealList.get(i).deal_name);
placesListItems.add(map);
}
new PlacesMapActivity(SinglePlaceActivity.this, lon, lat, name, add);
ListView lv = (ListView) findViewById(R.id.listView);
simpleAdapter = new SimpleAdapter(SinglePlaceActivity.this, placesListItems, R.layout.list_item_deal, new String[] {
DealItem.DEAL_ID, DealItem.DEAL_NAME }, new int[] { R.id.reference, R.id.name });
lv.setAdapter(simpleAdapter);
when i run this code i am getting answer like this
10-03 18:37:29.429: I/System.out(3957): DEAL NAME = Sinbad Cafe
10-03 18:37:52.369: I/System.out(3957): DEAL NAME = Coffee,Tea, Hot Milk
10-03 18:37:55.189: I/System.out(3957): DEAL NAME = Httpss
But I do not understand why I am getting an invalid value in ListView
Like below:
Httpss
Httpss
Httpss

The same map is added to the list several times.
Try moving the new HashMap<...>-line into the for-loop:
for (int i = 0; i < dealList.size(); i++) {
--> HashMap<String, String> map = new HashMap<String, String>();
map.put(DealItem.DEAL_ID, dealList.get(i).deal_id);
map.put(DealItem.DEAL_NAME, dealList.get(i).deal_name);
System.out.println("DEAL NAME = "+dealList.get(i).deal_name);
placesListItems.add(map);
}

+-------- HashMap<String, String> map = new HashMap<String, String>();
|
| for (int i = 0; i < dealList.size(); i++) {
+--------------->
map.put(DealItem.DEAL_ID, dealList.get(i).deal_id);
map.put(DealItem.DEAL_NAME, dealList.get(i).deal_name);
System.out.println("DEAL NAME = "+dealList.get(i).deal_name);
placesListItems.add(map);
}
Since you have your "HashMap" initialization outside your loop, you are actually overwriting the same hashmap and putting it back to the arraylist..
Try to move your HashMap initialization inside for-loop..

change code with following code it will solve your error.....
try {
for (int i = 0; i < dealList.size(); i++) {
HashMap<String, String> map = new HashMap<String, String>();
map.put(DealItem.DEAL_ID, dealList.get(i).deal_id);
map.put(DealItem.DEAL_NAME, dealList.get(i).deal_name);
System.out.println("DEAL NAME = "+dealList.get(i).deal_name);
placesListItems.add(map);
}

Related

Why wouldn't Java Map work? The function .put() not inserting the value and only inserting the key

When I try to insert a value relating to its key the value is not inserting inside the map. It seems like the "ids" doesn't have any value in it but it does.
Map<String, Vector<String>> graph = new HashMap<String, Vector<String>>();
ArrayList<String[]> words = new ArrayList<String[]>();
Vector<String> ids = new Vector<String>();
String[] id = null;
Scanner scanner = new Scanner(new FileReader(fInName));
while (scanner.hasNextLine()) {
words.add(scanner.nextLine().split("\\s+"));
}
for(int i = 0; i < words.size(); i++) {
id = words.get(i)[1].split("[,]", 0);
for(int j = 0; j < id.length; j++) {
ids.add(j, id[j]);
}
graph.put(words.get(i)[0], ids);
id = null;
ids.clear();
}
for (Map.Entry<String, Vector<String>> entry : graph.entrySet()) {
System.out.println("Key = " + entry.getKey() +
", Value = " + entry.getValue());
}
The put() function works by reference. So
put (key, ids)
stores a reference (memory pointer) to the same ids object that you are running the clear() function on. Trying to 'clean up' your memory is laudable, but in this case you're shooting your own foot. What you want is something like this
Map<String, Vector<String>> graph = new HashMap<String, Vector<String>>();
ArrayList<String[]> words = new ArrayList<String[]>();
Vector<String> ids;
String[] id = null;
Scanner scanner = new Scanner(new FileReader(fInName));
while (scanner.hasNextLine()) {
words.add(scanner.nextLine().split("\\s+"));
}
for(int i = 0; i < words.size(); i++) {
id = words.get(i)[1].split("[,]", 0);
ids = new Vector<String>();
for(int j = 0; j < id.length; j++) {
ids.add(j, id[j]);
}
graph.put(words.get(i)[0], ids);
}

Not able to retrieve hashmap from sharedPreferences

I am retrieving list of ParseObject from Parse and casting into list of HashMap,then converting it to JSONArray and storing in SharedPrefrences as String
List<HashMap<String, Object>> data = new ArrayList<HashMap<String, Object>>();
for (int i = 0; i < list.size(); i++) {
ParseObject foundObject = list.get(i);
HashMap<String, Object> industry = new HashMap<String, Object>();
industry.put("CategoryName", foundObject.get("category"));
industry.put("lastUpdated", new Date());
industry.put("Jobs", foundObject.getList("jobs"));
data.add(industry);
}
JSONArray result = new JSONArray(data);
editor.putString("Categories", result.toString());
editor.commit();
Then i am retrieving from locally saved String(JSONArray)
String storedCollection = pref.getString("Categories", null);
//Parse the string to populate your collection.
collection = new ArrayList<HashMap<String, Object>>();
if (storedCollection != null) {
try {
JSONArray array = new JSONArray(storedCollection);
HashMap<String, Object> item = null;
for (int i = 0; i < array.length(); i++) {
try {
JSONObject obj = new JSONObject((String) array.get(i));
Iterator<String> it = obj.keys();
item = new HashMap<String, Object>();
while (it.hasNext()) {
String key = it.next();
item.put(key, obj.get(key));
}
if (item == null) {
JSONObject obj2 = (JSONObject) array.get(i);
Iterator<String> it1 = obj2.keys();
item = new HashMap<String, Object>();
while (it1.hasNext()) {
String key = it.next();
item.put(key, obj2.get(key));
}
}
} catch (JSONException e) {
}
collection.add(item);
}
} catch (JSONException e) {
Log.e("JSON", "while parsing", e);
}
}
Which works fine on and above lollipop version but giving error on lower versions
org.json.JSONException: Unterminated array at character 21 of
{jobs=[Bar management, Baker, Bar service, Barista, Car park services,
Chef, Cleaning services, Cooking & food preparation], lastUpdated=Tue
Jun 28 10:22:03 GMT+05:30 2016, category=fulltime}
and sometimes getting this error
java.lang.ClassCastException: org.json.JSONObject cannot be cast to
java.lang.String
The problem is the array that you store is JSONArray of HashMaps. When you retrieve the array, the objects in the array are strings(representing HashMap). JSONObject obj = new JSONObject((String) array.get(i)); which you are trying to convert to JSONObject.This is the problem. Either you convert each of this string back to hashmap or you can use JSONObject in place of HashMap like this to store the data
public void storeInPrefs(){
JSONArray data = new JSONArray();
for (int i = 0; i < list.size(); i++) {
JSONObject industry = new JSONObject();
ParseObject foundObject = list.get(i);
try {
industry.put("CategoryName", foundObject.get("category"));
industry.put("lastUpdated", new Date());
industry.put("Jobs", foundObject.getList("jobs"));
data.put(industry);
}
catch (JSONException e) {
e.printStackTrace();
}
}
SharedPreferences preferences = this.getPreferences(MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putString("Categories", data.toString());
editor.commit();
}
And to parse the stored data and put it in collection, you can do this
public void parseStoredData(){
SharedPreferences pref = this.getPreferences(MODE_PRIVATE);
String storedCollection = pref.getString("Categories", null);
//Parse the string to populate your collection.
ArrayList<HashMap<String, Object>> collection = new ArrayList<HashMap<String, Object>>();
if (storedCollection != null) {
try {
JSONArray array = new JSONArray(storedCollection);
for (int i = 0; i < array.length(); i++) {
try {
JSONObject object = array.getJSONObject(i);
HashMap<String,Object> item = new HashMap<String, Object>();
Iterator<String> it = object.keys();
while (it.hasNext()) {
String key = it.next();
item.put(key, object.get(key));
}
collection.add(item);
} catch (JSONException e) {
e.printStackTrace();
}
}
} catch (JSONException e) {
Log.e("JSON", "while parsing", e);
}
}
}
In my opinion this would be easy for you.
try to use JSONObject object = new JSONObject(industry);
instead of JSONArray result = new JSONArray(data);
Thie object.toString() is like {"Jobs":["Bar management","Baker","Bar service"],"lastUpdated":"Tue Jun 28 13:54:24 GMT+08:00 2016","CategoryName":"fulltime"}
And the result.toString() is like [{"Jobs":["Bar management","Baker","Bar service"],"lastUpdated":"Tue Jun 28 13:54:24 GMT+08:00 2016","CategoryName":"fulltime"}]
I think the object is what you really want, and use JsonObject also when retrieving.
Hope helpful.
Addtionally, you can use this to verify your result.

outOfMemory in for loop java

I am iterating 500,000 items using for loop , after 300, 000 item i am getting Out of memory , I have also tried to split loop in 100,000 still, but that also didn't work. When I increased memory in runConfig-xms10g, its working fine. Can anyone tell me how to split and free memory or any other way to iterate large number of recods.
protected Map<Long, Map<String, String>> getExistingItems()
{
Map<Long, Map<String, String>> items = new HashMap<Long, Map<String, String>>();
for (Item item : itemMaster.getItems()) {
if (item.getExpirationDate() == null && !items.containsValue(item.getItemId())) {
Map<String, String> item_hash = new HashMap<String, String>();
if (item.getEffectiveDate() != null)
item_hash.put("effectiveDate", sdf.format(item.getEffectiveDate().getTime()));
for (ItemMasterAttributeValue attrVal : item.getItemMasterAttributeValues()) {
item_hash.put(attrVal.getId().getItemMasterAttribute().getCode(), attrVal.getValue());
}
items.put(item.getItemId(), item_hash);
}
}
after splitting below is code:
protected Map<Long, Map<String, String>> getExistingItems()
{
Map<Long, Map<String, String>> items = new HashMap<Long, Map<String, String>>();
java.util.Date date = new java.util.Date();
System.out.println("before getItems : " + new Timestamp(date.getTime()));
Collection<Item> allItems = itemMaster.getItems();
System.out.println("after getItems : " + new Timestamp(date.getTime()));
int split = (allItems.size() / 100000);
Map<Integer, Collection<Item>> splitMap = new HashMap<Integer, Collection<Item>>();
Collection<Item> tempCollection = new ArrayList<Item>();
int splitKey = 1;
int key = 1;
for(Item item : allItems)
{
tempCollection.add(item);
if(splitKey / 100000 >= key && splitKey % 100000 == 0)
{
splitMap.put(key, tempCollection);
tempCollection = new ArrayList<Item>();
key++;
}
splitKey++;
}
splitMap.put(key, tempCollection);
System.out.println("map size " + splitMap.size());
for(int i = 1; i <= split + 1; i++)
{
System.out.println("i is :" + i + " " + Calendar.getInstance().getTime());
for(Item item : splitMap.get(i))
{
if(!items.containsKey(item.getItemId()))
{
Map<String, String> item_hash = new HashMap<String, String>();
if (item.getEffectiveDate() != null)
item_hash.put("effectiveDate", sdf.format(item.getEffectiveDate().getTime()));
for (ItemMasterAttributeValue attrVal : item.getItemMasterAttributeValues()) {
item_hash.put(attrVal.getId().getItemMasterAttribute().getCode(), attrVal.getValue());
}
items.put(item.getItemId(), item_hash);
}
}
System.gc();
}

List renderer issue in codenameone

I used list renderer and all works fine. Then I kept a extract last clicked item as follows: There are 3 buttons in the renderer. button1 works in all, however button2 and button3 works in some and doesn't work in other? why is it?
If I remove if (lastClickedButton != null) from the code below, it gives NullPointerException for the same button which works in other list items before.
MyCode:
#Override
protected boolean initListModelListEmergencyList(List cmp) {
cmp.setModel(new com.codename1.ui.list.DefaultListModel(emergencyPoliceArray));
cmp.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
for (int i = 0; i < emergencyPoliceArray.size(); i++) {
if (cmp.getSelectedItem() == emergencyPoliceArray.get(i)) {
lastClickedButton = ((GenericListCellRenderer) cmp.getRenderer()).extractLastClickedComponent();
if (lastClickedButton != null) {
System.out.println("Phn no: " + lastClickedButton.getText());
}
}
}
}
}
);
return true;
}
MyConnection:
private void showEmergencyDetails() {
JSONParser p = new JSONParser();
Hashtable<String, Object> test;
try {
test = p.parse(new InputStreamReader(is));
Vector emergencyVector = (Vector) test.get("root");
emergencyPoliceArray = new ArrayList<Map<String, String>>();
for (int j = 0; j < emergencyVector.size(); j++) {
Hashtable hm = (Hashtable) emergencyVector.get(j);
String title = (String) hm.get("title");
String location = (String) hm.get("location");
Vector phn = (Vector) hm.get("phone");
for (int i = 0; i < phn.size(); i++) {
Hashtable hphn = (Hashtable) phn.get(i);
String phone1 = (String) hphn.get("phn1");
String phone2 = (String) hphn.get("phn2");
String phone3 = (String) hphn.get("phn3");
HashMap<String, String> mp = new HashMap<String, String>();
mp.put("Phn", phone1);
mp.put("Phone2", phone2);
mp.put("Phone3", phone3);
mp.put("NameHeading", "Name");
mp.put("PhnHeading", "Phn no.");
mp.put("LocationHeading", "Location");
mp.put("Title", title);
mp.put("Name", title);
mp.put("Location", location);
emergencyPoliceArray.add(mp);
}
}
} catch (IOException ex) {
}
showForm("EmergencyListDetails", null);
}
If there is variance between the renderer entries (e.g. one entry has the button while another doesn't) this might impact all the list and not just the entry where the button is visible.
When you have interaction we strongly recommend avoiding list. Its hackish at best for such use cases and doesn't provide any performance advantages over container for such common cases.

Fetch Values from SimpleAdapter to array[]

Is it possible to transfer values from SimpleAdapter to array[]. I am getting values in SimpleAdapter from ArrayList<HashMap<String, String>> and want to pass these values from SimpleAdapter to array[].
static ArrayList<HashMap<String, String>> contactList = new ArrayList<HashMap<String, String>>();
SimpleAdapter adapter = new SimpleAdapter(this, contactList,R.layout.list_item,new String[] {android_H_NAME}, new int[] {R.id.name});
String[] hospFields = //want to get values here from adapter
Modify and use this:
ArrayList<String> listItems = new ArrayList<String>();
for (int i = 0; i < result.length(); i++) {
try {
listItems
.add(result.getJSONObject(i)
.getString(BsharpConstant.NAME_CONSTANT)
.toString());
} catch (Exception ex) {
ex.printStackTrace();
}
}
Inside oncreate method:
ListView list = (ListView) findViewById(R.id.idOfUrView);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
ActivityName.this,
android.R.layout.simple_list_item_1, listItems);
list.setAdapter(adapter);
list.setOnItemClickListener(this);//if u need this until not required
Use this want to stores the value in item click:
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
String clickedItemName = (String) listOfProductsCategory
.getItemAtPosition(position);
int clickedItemId = (int) listOfProductsCategory
.getItemIdAtPosition(position);
// implement your login to store the value
//by using for loop listItems[i] ,i++
Toast.makeText(this.getActivity(),
"Custom text : " + clickedItemName,
Toast.LENGTH_SHORT).show();
//call your method if u want
}
There is no possibility to access the data directly, but you can use (in general):
Object[] o = new Object[adapter.getCount()];
for (int i = 0; i < adapter.getCount(); i++) {
o[i] = adapter.getItem(i);
}
to create a copy of your Adapter data. If you want just to extract specific values use:
String[] hospFields = new String[adapter.getCount()];
for (int i = 0; i < adapter.getCount(); i++) {
HashMap<String, String> rowData = adapter.getItem(i); //gets HashMap of a specific row
String name = rowData.get("name"); //gets the field name of that row
hospFields[i] = name; // copies field into your array
}

Categories