I have an ArrayList full of custom objects. I need to save this ArrayList to a Bundle and then retrieve it later.
Having failed with both Serializable and Parcelable, I'm now simply trying to somehow save the objects that are associated with the indexes in the ArrayList, then checking these when restoring the Bundle and adding the objects back in.
What I have is something like this:
When saving the Bundle:
//Create temporary array of the same length as my ArrayList
String [] tempStringArray = new String[myList.size()];
//Convert the enum to a string and save it in the temporary array
for (int i = 0; i<myList.size();i++){
tempStringArray [i] = myList.get(i).getType(); //returns the enum in string form
}
//Write this to the Bundle
bundle.putStringArray("List", tempStringArray);
So I now have an array of strings representing the enum types of the objects that were originally in the ArrayList.
So, when restoring the Bundle, what I'm trying is something like this:
//Temporary string array
String[] tempStringArray = savedState.getStringArray("List");
//Temporary enum array
ObjectType[] tempEnumArray = new ObjectType[tempStringArray.length];
for (int i = 0; i<tempStringArray.length;i++){
tempEnumArray[i]=ObjectType.valueOf(tempEnemies[i]);
}
So, now I have the enum type of each item that was originally in the ArrayList.
What I'm now trying to do now, is something like (would go inside the for loop above):
myList.add(tempEnumArray[i].ObjectTypeThisEnumRefersTo());
Obviously the "ObjectTypeThisEnumRefersTo()" method above doesn't exist but this is ultimately, what I'm trying to find out. Is this possible or perhaps there is some other way of doing this?
To get an enum value of the enum type Enemy from a string, use
Enemy.valueOf(String).
Enemy.valueOf("SPIDER") would return Enemy.SPIDER, provided your enum looks like
enum Enemy { SPIDER, BEE};
EDIT: It turns out Zippy also had a fixed set of Enemy objects, each mapped to each value of EnemyType, and needed a way to find an Enemy from a given EnemyType. My suggestion is to create a
HashMap<EnemyType, Enemy>
and put all the objects in there upon creation, then at deserialization convert strings to enum values and enum values to Enemy objects using the hashmap.
It later occurred to me though that depending on how much logic you have in Enemy, you might want to consider scrapping either Enemy or EnemyType and combine them into one parameterized enum, similar to the example with Planet over here:http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html
That would spare you from having to go two steps from a string to your final object and simplify things a bit as you wouldn't need any hashmap after all.
When I try to persist a two dimensional ArrayList I get the following error:
java.lang.IllegalArgumentException: cng_content: java.util.ArrayList is not a supported property type.
I am constructing a representation of a matrix using two array lists and trying to persist it to the data store.
Key cngKey = KeyFactory.createKey("CNG", jsonCNG.cNGID);
Entity cngEntity = new Entity("CNG", cngKey);
cngEntity.setProperty("cng_name", jsonCNG.cNGName);
cngEntity.setProperty("cng_type", jsonCNG.cNGType);
cngEntity.setProperty("cng_content", cng);
In the code snippet cng is of type:
ArrayList<ArrayList<String>>
I initially used
ArrayList<HashMap<Byte,Boolean>>
as the type of the object. However, found that HashMaps are not supported by GAE datastore. Further, I am not intending to query on the stored object. Just to store and retrieve them.
If you are not querying, persist them as json or some other text format. Beware of maximum entity size.
The setProperty(name, value) method takes supported java types and Collection of supported java types (this includes ArrayList). However collection inside a collection is not a supported type.
These are called multi-valued properties and have a purpose - each value of a collection gets it's own index entry so queries can actually find entities based on values inside collections.
In your case you'd be best serialising one dimension of a 2D list into a byte array and store it inside a Blob, then store all blobs as List<Blob>.
Use EmbeddedEntity which can be stored as a property on your entity. Since you are only using 2D, set each array as a property on the EmbeddedEntity with the key being a number but represented in string format like "1", "2", "3".
More Specically:
Entity e = new Entity("2d");
EmbeddedEntity ee = new EmbeddedEntity();
ArrayList<String> x = new ArrayList<String>();
// add stuff to x
ArrayList<String> y = new ArrayList<String>();
// add stuff to y
ArrayList<String> z = new ArrayList<String>();
// add stuff to z
ee.setProperty("1", x);
ee.setProperty("2", y);
ee.setProperty("3", z);
e.setProperty("2dArray", ee);
I typed this out with out testing so may have syntax errors
I have seen this question and understand the answer, but can not use it in my scenario.
My scenario: I retrieve data via JPA from a mysql database and want to put this data into a JSONObject like this
{
"A":["1","2","3"],
"B":["1","2","3","4"],
"C":["1","2"]
}
The problem is I do not know how many arrays I will retrieve. It could be 1 or it could be 200, depending on the data in the database.
If I append the data into a JSONObject like this:
import org.apache.tapestry5.json.JSONObject
// ...
JSONObject data = new JSONObject();
for (Value val : values) data.append(val.getName(), val.getValue());
I'll get
{"val_name": [[["1"],"2"],"3"], ...}
Is there a way to use JSONOBject.append without creating JSONArrays and puting them into the JSONObject, which will result in a nested JSONObject?
A JSON object is a "dictionary" -- a map between name and value. A JSON array is a sequential list of values, with only the ordinal position of the value identifying it. It makes no sense to "append" to the object -- you add new name/value pairs to it (although they apparently call it appending, just to confuse you). If, within an object, you want something like "A":["1","2","3"] then you necessarily must insert an array (as the value of a name/value pair) into the object.
But note that either before inserting the array into the object or after you can append additional values to the array. You just need to get/save a reference to the array.
In your above example you're making the mistake of appending to the object rather than the array.
I'm having some difficulties parsing a JSON package in Android.
I currently have everything set up so the JSON is an array of objects, then each object has an array of attributes. For example, say I have an object called Colors in my package. Then each Color entry would be in the Colors object. Each Color entry would also have entries for R, G, B values.
This type, I can deal with fine. However, I'm now running into an instance where one of those entries (where the R,G,B values would be) has an array within it. I'm not sure how to go about accessing that and processing it.
I'm going to update with an example of the JSON package, since I'm worried I wasn't very clear.
Edit: Here's the JSON. Say I want to access the R value in the ColorOverlays.
{"Package":[
{"Things":[{"ProgramId":73,"TypeId":68,"CategoryId":null,"CategoryName":null,"ThingId":121,"ThingName":"Mahalo","ThingDescription":"Get your festival on and snap some shots!","ThingPrice":0.00,"SellerProductId":null,"Number2":1342655700,"Number1":1342655700,"IsAvailable":true,"ImageOverlays":[{"ThingId":121,"ThingOverlayId":295,"ImageOverlayBase64":null,"ImageOverlayFileTypeExtension":null,"Width":1024,"Height":1024,"A":1.00000,"BlendModeId":1,"OrderNum":2,"IsUseSource":false}],"ColorOverlays":[{"ThingId":121,"ThingOverlayId":294,"R":157.00000,"G":71.00000,"B":187.00000,"A":0.52873,"BlendModeId":6,"OrderNum":1}],"ThingsampleImageBase64":null,"ThingsampleImageFileTypeExtension":"","ThingsampleImageWidth":546,"ThingsampleImageHeight":546,"Captures":[{"ThingCaptureId":87,"ThingId":121,"CaptureFrameOverlayId":null,"IsRemoved":false,"AddDate":1342637814,"LastUpdated":1342637814,"Saturation":0.0,"Contrast":0.0,"Brightness":0.0,"Low":null,"Mid":null,"High":null,"IsBlackWhite":null,"IsInvert":null,"IsSepia":null}],"IsRemoved":false},{"ProgramId":73,"TypeId":68,"CategoryId":null,"CategoryName":null,"ThingId":122,"ThingName":"Lots of Love","ThingDescription":"Use this one!","ThingPrice":0.00,"SellerProductId":null,"Number2":1342667100,"Number1":1342667100,"IsAvailable":true,"ImageOverlays":[{"ThingId":122,"ThingOverlayId":298,"ImageOverlayBase64":null,"ImageOverlayFileTypeExtension":null,"Width":1024,"Height":1024,"A":1.00000,"BlendModeId":4,"OrderNum":3,"IsUseSource":false}],"ColorOverlays":[{"ThingId":122,"ThingOverlayId":296,"R":213.00000,"G":86.00000,"B":143.00000,"A":0.77777,"BlendModeId":4,"OrderNum":1},{"ThingId":122,"ThingOverlayId":297,"R":127.00000,"G":127.00000,"B":127.00000,"A":0.50000,"BlendModeId":1,"OrderNum":2}],"ThingsampleImageBase64":null,"ThingsampleImageFileTypeExtension":"","ThingsampleImageWidth":546,"ThingsampleImageHeight":546,"Captures":[{"ThingCaptureId":88,"ThingId":122,"CaptureFrameOverlayId":null,"IsRemoved":false,"AddDate":1342649164,"LastUpdated":1342649164,"Saturation":0.0,"Contrast":0.0,"Brightness":0.0,"Low":null,"Mid":null,"High":null,"IsBlackWhite":null,"IsInvert":null,"IsSepia":null}],"IsRemoved":false}]}
]}
If this is not something that you would throw away after the first use, then you might consider taking this up a level by modeling Java objects after your domain.
Use any online JSON visualizer to see your JSON in 3D.
Then, follow the following tutorial.
http://java.sg/parsing-a-json-string-into-an-object-with-gson-easily/
A sample of your code would be most helpful to try to help. Depending on how your RGB value array is built and passed. If it's a simple comma delimited string, then you could do:
try {
JSONArray jArray = new JSONArray(jString);
for (int i=0; i<jArray.length(); i++) {
JSONObject jo = jArray.getJSONObject(i);
String RGBVal = jo.getString("rgb_list");
String[] rgbArray = RGBVal.split(",");
....
Again, depends on how the entry is passed in JSON string.
Nevermind...
I want to make a deep copy method. I seeked help here the other day with this issue, but that was for a copy constructor. Now I need a regular method. I have the code created (nonworking), but I'm just not understanding it completely.
public GhostList deepCopy(){
int length=this.getLength();
GhostList jadeed=new GhostList();
Ghost[] data = new Ghost[length];
for (int i=0;i<this.getLength();i++){
data[i] = new Ghost();
data[i].setX(this.ghosts[i].getX());
data[i].setY(this.ghosts[i].getY());
data[i].setColor(this.ghosts[i].getColor());
data[i].setDirection(this.ghosts[i].getDirection());
}
return jadeed;
}
Now when I create a new GhostList named jadeed, and then under that I create a new data array of ghosts, does it know that data belongs to the jadeed GhostList? I dont see how the two can be associated, even though they should be.
Also, I'm not getting the lengths to match up for the copy and this.object. What is my problem?
You created a new GhostList and a new Ghost array.
You fill in the Ghost array and return the GhostList but the returned GhostList has nothing to do with the Ghost array.
You should add all the new ghosts to the GhostList
First, you mentioned a copy constructor. If you already have that working, then all you need to do in your deepCopy method is:
return new GhostList(this);
Let's forget that for now and get back to the code you posted. You are creating an array named data but you never used it anywhere. Aren't you supposed to assign this array to jadeed? Something like:
jadeed.ghosts = data;
And finally, instead of calling the method deepCopy, it would be better to call it clone and implement the Cloneable interface. Doing this allows everyone to know how to get a copy of your object using a standard interface.
Your GhostList class will have as its data member a reference to the array of Ghost. You've not shown us the class definition, so lets say that member is named foo. Now all you need to do is make the foo reference of the newly created jadeed object refer to the array of Ghost which you've created and populated. You can do it as:
jadeed.foo = data;
before you return jadeed.
If GhostList and everything it's composed of is Serializable, you can serialize the GhostList instance into a byte array and re-read it. It's a few lines of code, unless you use `Jakarta Commons Lang - one line of code:
http://commons.apache.org/lang/api-2.5/org/apache/commons/lang/SerializationUtils.html#clone%28java.io.Serializable%29