I want to call App Engine Endpoint with an Array of different objects, Say String, int and int.
I have tried couple of suggestions mentioned in StackOverflow, but those are not supporting as the Array of objects are of different types.
I have created a class JsonList<T> to save an object and ContainerInfo class holding String, int and int as members with get and set function calls.
When I try to call endpoint as Endpoint(User, JsonList<ContainerInfo>), IllegalArgumentException Parameterized type <ContainerInfo> not supported error is thrown.
Is there a workaround possible to achieve this?
What I have found is Endpoint methods won't let you pass in two or more objects (unless they are primitive types like String, etc.). In your example you are passing in User and JsonList objects.
What you can do is create a pojo wrapper class when doing that and inside there have the User object as well as your JsonList array there. Then inside your Endpoint method unwrap everything.
Endpoint(MyWrapper)
Note: your JsonList may or may not have to implement Serializable if you intent to call your Endpoints method from a mobile client like Android.
EDIT:
Here is an example:
public final class SomeObject
{
private String stringValue;
private int intValue;
// add more
public SomeObject(String stringValue, int intValue)
{
this.stringValue = stringValue;
this.intValue = intValue;
}
public String getString()
{
return stringValue;
}
public String getInt()
{
return intValue;
}
}
public final class someObjectWrapper
{
private User user;
private List<SomeObject> someObjectList
public someObjectWrapper(List<SomeObject> someObjectList, int user) {
this.someObjectList = someObjectList;
this.user = user;
}
public List<SomeObject> getSomeObjectList() {
return someObjectList;
}
public void setSomeObjectList(List<SomeObject> someObjectList) {
this.someObjectList = someObjectList;
}
public int getUser() {
return user;
}
public void setUser(int user) {
this.user = user;
}
}
Then inside your API method, just get those properties from the wrapper as new variables and then work with them however you want.
Related
I have created a simple class:
public class Example
{
private String name;
private int age;
// With getters and setters.
}
that I would like "put" into a chronicle map:
ChronicleMap<String,Example> map = ChronicleMapBuilder
.of(String.class, Example.class)
.name("example-map")
.entries(5_000)
.averageValue(new Example())
.valueMarshaller(ExampleSerializer.getInstance())
.averageKey("Horatio")
.createPersistedTo(new File("../logs/example.txt"));
However, I do not fully understand how to implement the ExampleSerializer class because I am not sure how the string member variables should be handled. How do I size strings? In the read and write methods, how do I read the string member variable, and how do I write the string member variable respectively. Pls note that on average, the name member string length will be between 7-10 characters. I have created the serializer below:
public class ExampleSerializer implements SizedReader<Example>,SizedWriter<Example>
{
private static ExampleSerializer INSTANCE = new ExampleSerializer();
public static ExampleSerializer getInstance() { return INSTANCE; }
private ExampleSerializer() {}
#NotNull
#Override
public Example read(Bytes in, long size, #Nullable Example using)
{
if (using == null)
using = new Example();
using.setAge(in.readInt());
using.setName(in.readUtf8()); // NOT SURE IF THIS IS CORRECT FOR A STRING
return using;
}
#Override
public long size(#NotNull Example toWrite)
{
return Integer.BYTES + ???; // NOT SURE WHAT THE SIZE SHOULD BE FOR STRING MEMBER?
}
#Override
public void write(Bytes out, long size, #NotNull Example toWrite)
{
out.writeInt(toWrite.getAge());
out.writeUtf8(toWrite.getName()); // NOT SURE IF THIS IS CORRECT FOR A STRING
}
}
I'm writing an android application with java code. The app can support english and italian. Inside the app, there is a spinner that take its values from an enumerate class, the following:
public enum ElementTypesEnum {
MEET("Meet"),
CEREAL("Cereal"),
FISH("Fish"),
OTHER("Other");
private String elementType;
ElementTypesEnum(String elementType) {
this.elementType = elementType;
}
public String getElementType() {
return elementType;
}
}
I want to initialize the values of the enumerate with the values contained in my local string resource file (R.string.value_1). In this class I don't have an instance of the resource file, since I don't have an instance of Context. How can I do this? Thank you in advance, Marco
Use the resource ID then fetch the strings with your spinner's Context when you populate it.
public enum ElementTypesEnum {
MEAT(R.string.meat),
CEREAL(R.string.cereal),
FISH(R.string.fish),
OTHER(R.string.other);
#StringRes
private int elementType;
ElementTypesEnum(#StringRes int elementType) {
this.elementType = elementType;
}
public int getElementType() {
return elementType;
}
}
I create a model called Review. There are two activities (QualityReivewActivity.java & FairnessReivewActivity.java) will call the model whenever user leaves a comment.
I want to
public class Review {
float fairness_rating; //change the name to quality_rating
String post_id;
String review_time;
String reviewer_id;
String text_review;
public Review(){
//
}
Review(float fairness_rating, String post_id, String review_time, String reviewer_id, String text_review){
this.fairness_rating=fairness_rating;
this.post_id=post_id;
this.review_time=review_time;
this.reviewer_id=reviewer_id;
this.text_review=text_review;
}
public float getFairness_rating() {
return fairness_rating;
} //change to getQuality_rating if actitivty is QualityReivewActivity.java
public String getPost_id() {
return post_id;
}
public String getReview_time() {
return review_time;
}
public String getReviewer_id() {
return reviewer_id;
}
public String getText_review() {
return text_review;
}
}
and this is the segment of code of QualityReivewActivity
Review c = new Review(mRatingBar.getRating(), post_id, timedComment.toString(), reviewer_uid, my_comment.getText().toString()); //
However, the QualityReviewActivity always shows "fairness_rating". How can I make a dynamic model name to change to "quality_rating" if I am calling from QualityReviewActivity?
You can solve it by using enum.
public enum ratingType {
Quality,
Fairness
}
Then use that enum in your function.
public float get_rating(ratingType type) {
switch (type) {
case Quality:
return quality_rating;
case Fairness:
return fairness_rating;
}
}
After that, depending on the class, you can pass the necessary arguments and it will work.
I'm not good at Java, so it may not work if I write it as it is, but the idea is ok.
I don't want to do the deep copy way.
Say, I have a field of some mutable type, a x,y,z Coordinate for example. Occasionally, I need to expose this field to some viewers. And I want it be read-only. I remember reading something like a wrapper to do these kind of stuff, but I don't remember the details.
The x,y,z Coordinate example may be too simple because x,y,z are primitive type. So getX() always return a copy.
I want a general solution even if the x,y,z fields are of yet another mutable type.
Can anybody help?
EDIT:
public class Client
{
public static final Holder holder = new Holder();
public static void main(String[] args)
{
UserWrapper user = holder.getUser();
System.out.println(user); //UserWrapper{user=User{address=Address{street='street 101'}}}
user.getAddress().setStreet("mars"); //UserWrapper{user=User{address=Address{street='mars'}}}
System.out.println(user);
}
}
public class Holder
{
private User user;
public Holder()
{
user = new User();
Address address = new Address();
address.setStreet("street 101");
user.setAddress(address);
}
public UserWrapper getUser()
{
return new UserWrapper(user);
}
}
public class User
{
private Address address;
public Address getAddress()
{
return address;
}
public void setAddress(Address address)
{
this.address = address;
}
}
public class UserWrapper
{
private User user;
public UserWrapper(User user)
{
this.user = user;
}
public Address getAddress()
{
return user.getAddress();
}
}
EDIT:
credit to I don't know who(he deletes the answer), I find this link he mentioned in his original post very helpful.
The traditional ways:
deep copy - prevents mutations from impacting the client who is reading
immutable objects - instead of copying for the client, you copy to update and the client gets an old pointer reference.
customer iterator - you provide your own iterator / navigation interface, which is sensitive to a "version" field embedded with the data structure. Before visiting each element, it checks that the version has not been changed since the iterator was created (java collections does this).
strong synchronization - while a reader is reading, the reader holds a lock on the data structure preventing update. Generally a bad solution, but occasionally useful (included for completeness).
lazy copy - you construct an object that mostly references the original, but is triggered (as a listener) to the original, such that when a mutation is done on the original, you copy the pre-mutated value locally.
This is like a lazy deep copy strategy.
There's others, but this should get you started.
There is no built-in mechanism in Java that will enable you to do that. Usually, if you move instances around, you'd either:
Use immutable objects
Pass on copies of the objects
Since you don't want/can't choose either of these ways, you'll need to use an alternative. There are a lot of different ways to implement this depending on your requirements and how complex is your class structure, but the general approach would be to publish an immutable wrapper instead of the original.
Here are some examples:
public class XYZ {
public int x, y, z;
}
public class XYZWrapper {
private XYZ xyz;
public XYZWrapper(XYZ xyz) {
this.xyz = xyz;
}
public int getX() { return x; }
public int getY() { return y; }
public int getZ() { return z; }
}
public class Address {
public String name;
public XYZ xyz;
}
public class AddressWrapper {
private String name; // Note that this could be public since any String is immutable
private XYZWrapper xyzWrapper;
public AddressWrapper(String name, XYZ xyz) {
this.name = name;
this.xyzWrapper = new XYZWrapper(xyz);
}
public String getName() {
return name;
}
public XYZWrapper getXYZWrapper() {
return xyzWrapper;
}
}
Now, if instead of XYZ and Address classes, you work with interfaces, you can have 2 implementations (e.g. XYZMutable & XYZImmutable) which will allow you to abstract which type of class you're returning, and also will enable you to create an instance of XYZImmutable from an instance of XYZMutable (assuming that the interface defines only & all getter methods).
One more note about this approach (especially if you do it the preferred way by using interfaces): Even if you have a complex class hierarchy, you can do this relatively effortlessly by creating a generator class that receives an interface instance, a mutable implementation instance and returns an immutable implementation instance as the return value.
Perhaps you're thinking of the "copy on write" idiom. This allows you to avoid copying unless you have to. It's use is generally not recommended because it is not thread-safe unless you use synchronization which will unnecessarily slow down single-threaded applications.
It works by keeping a reference count of its internal data; something like this untested bit of code:
public class User
{
private int addressReferenceCount;
private Address address;
public User(Address address) {
addressReferenceCount = 0;
this.address = address;
}
public Address getAddress() {
addressReferenceCount++;
return address;
}
public void setAddress(Address address)
{
if (addressReferenceCount == 0) {
this.address = address;
}
else {
this.address = new Address(address);
addressReferenceCount = 0;
}
}
}
This ensures that user code like this will get different addresses when necessary:
User u = new User(new Address("1 Acacia Avenue"));
Address oldAddress = u.getAddress();
Address stillOldAddress = u.getAddress();
u.setAddress(new Address("2 Acacia Avenue"));
Address newAddress = u.getAddress();
assert (oldAddress == stillOldAddress); // both refer to same object
assert (oldAddress != newAddress);
I have encountered a weird problem in my app (java).
I have an enum. Something like that
public enum myEnum implement myIntrface{
valueA(1),valueb(2),valuec(3),valued(4)
private int i;
// and then - a constructor
public MyEnum(int number){
i = number;
}
private MyObj obj = new MyObj;
// getter and setter for obj
}
and in another class I have this
MyEnum.valueA.setObj(new Obj(...))
in briefe - I have an enum with a private instance member that has a set and a get.
So far so good -
The only thing that amazes me is that later on I look at the value of the MyEnum.valueA().obj is null.
there is nothing that updates the value to null, I have even gave it a default value in the constructor and I still see it null later.
any suggestions?
Enums should be un-modifiable classes so you shouldn't really be doing this. If your looking to modify the state of a type based object like an enum you should use an final class approach with embedded constants. Below is an example of a class based approach with a modifiable name an a un-modifiable name...
public final class Connection {
public static final Connection EMAIL = new Connection("email");
public static final Connection PHONE = new Connection("phone");
public static final Connection FAX = new Connection("fax");
/**/
private final String unmodifiableName; //<-- it's final
private String modifiableName;
/*
* The constructor is private so no new connections can be created outside.
*/
private Connection(String name) {
this.unmodifiableName = name;
}
public String getUnmodifiableName() {
return unmodifiableName;
}
public String getModifiableName() {
return modifiableName;
}
public void setModifiableName(String modifiableName) {
this.modifiableName = modifiableName;
}
}
The purpose of enums is to represent constant values. It does not make any sense to set the fields of a constant value.
You should declare your fields as final, and use the constructor to initialize all of them.
For reference, the following code works as expected:
public class Test {
public static enum MyEnum {
valueA(1),valueb(2),valuec(3),valued(4);
private int i;
private Object o;
private MyEnum(int number) {
i = number;
}
public void set(Object o) {
this.o = o;
}
public Object get() {
return o;
}
}
public static void main(String[] args) {
System.out.println(MyEnum.valueA.get()); // prints "null"
MyEnum.valueA.set(new Integer(42));
System.out.println(MyEnum.valueA.get()); // prints "42"
}
}
the cause of this problem is the db40 framework . It loads an enum from the db using reflection. This is well documented .
http://developer.db4o.com/Forums/tabid/98/aft/5439/Default.aspx