How can i achieve this without getting
error: cannot inherit from final ArraySet
ArraySet<MyObject>objectList = new ArraySet<MyObject>(){
#Override
public boolean equals(Object object) {
return ((MyObject)this).getId()==((MyObject)object ).getId();
}
};
ArraySet is a final class, meaning you can't inherit from it. You are trying to create an anonymous subclass when you write
ArraySet<MyObject>objectList = new ArraySet<MyObject>(){
#Override
public boolean equals(Object object) {
return ((MyObject)this).getId()==((MyObject)object ).getId();
}
};
What you really want to do is implement equals (and hashcode) for MyObject:
public class MyObject {
...
#Override
public boolean equals(Object other) {
if (other instanceof MyObject) {
return getId() == ((MyObject) other).getId();
}
return false;
}
}
Then, the ArraySet will work as you intend
Related
How I can Notify on Multiple variables update?
Is there any method to detect and separatenotifyObservers?
public class AnimalWeightObservable extends Observable {
public long animalId;
public long weigh;
public long getAnimalId() {
return animalId;
}
public AnimalWeightObservable setAnimalId(long animalId) {
this.animalId = animalId;
this.setChanged();
this.notifyObservers(animalId);
return this;
}
public long getWeigh() {
return weigh;
}
public AnimalWeightObservable setWeigh(long weigh) {
this.weigh = weigh;
this.setChanged();
this.notifyObservers(weigh);
return this;
}
}
How can detect witch variable has changed?
How about wrapping animalId and weight inside another type: for example AnimalProperty
class AnimalProperty<T> {
String propertyName;
T property;
AnimalProperty(String name, T property) {
this.propertyName = name;
this.property = property;
}
}
so your code would look like this:
public class AnimalWeightObservable extends Observable {
public AnimalProperty animalId;
public AnimalProperty weigh;
//...
//...
public AnimalWeightObservable setWeigh(AnimalProperty weigh) {
this.weigh = weigh;
this.setChanged();
this.notifyObservers(weigh);
return this;
}
}
then in the Observer's update(...) method switch on the propertyName to know which property is updated
I have a class variable that is final and is set in the constructor. When I check the value of it in the constructor for the abstract class and the subclass it's the correct value. But when I check it later in a method it's always false. Here's my code.
abstract class AbstractArticleObject extends StructureObject {
final boolean firstArticle;
AbstractArticleObject(Element element, boolean firstArticle) {
super(element);
this.firstArticle = firstArticle;
...
}
}
class ArticleObject extends AbstractArticleObject {
ArticleObject(Element element, boolean firstArticle) {
super(element, firstArticle);
// In this method, firstArticle is whatever was passed in, which is sometimes true.
Log.v(title, String.format(String.valueOf(this.firstArticle));
}
#Override
StructureState getState() {
// In this method, firstArticle is always false.
Log.v(title, String.format(String.valueOf(firstArticle));
if (...) {
...
} else if (...) {
if (firstArticle) {
return StructureState.CAN_OPEN;
} else {
...
}
}
return StructureState.NOT_SET;
}
}
If I'm setting the value in the constructor, and the value is final, why is it returning false even when it was set to true?
Where is getState() called from?
It is possible for final variables to "change" if you access them before they're ever initialized. Consider the following tiny program:
public class Test {
private final boolean value;
public Test() {
doSomething();
this.value = true;
doSomething();
}
private void doSomething() {
System.out.println(value);
}
public static void main(String[] args) {
new Test();
}
}
The output of this program will be
false
true
So, if your getState() method is called from e.g. the constructor of StructureObject, then it will be called before the AbstractArticleObject constructor initializes firstArticle, and it will be false.
I have a custom class:
private class FeatureIndexEntry {
public String feature_name;
public int index;
public FeatureIndexEntry (String feature_name) {
this.feature_name = feature_name;
}
#Override
public int hashCode () {
return this.feature_name.hashCode();
}
#Override
public boolean equals (Object o) {
if (this == o) return true;
if (o instanceof String) {
return ((String) o).equals(this.feature_name);
}
if (!(o instanceof FeatureIndexEntry)) return false;
return ((FeatureIndexEntry) o).feature_name.equals(this.feature_name);
}
}
I also have HashSet<FeatureIndexEntry> feature_index;, there is something already in it.
feature_index.add( new FeatureIndexEntry("gx") );
feature_index.add( new FeatureIndexEntry("gy") );
Now I want to check whether String "gx" in it, I called feature_index.contains("gx"), but the result is false.
After overriding method hashCode() and equals(), why it still cannot search String in it?
I checked the result o instanceof String in equals, which is always false, but no other types are involved.
When I create a new FeatureIndexEntry object it works fine.
FeatureIndexEntry a = new FeatureIndexEntry("gx");
feature_index.contains(a); // true
Thanks for your reading, any help will be appreciated.
You are actually adding Objects of FeatureIndexEntry, and seraching for String type object. How will this work..??
Modify your Test class as below.
public class Test2 {
public static void main(String[] args) {
HashSet<FeatureIndexEntry> feature_index = new HashSet<FeatureIndexEntry>();
FeatureIndexEntry f1 = new FeatureIndexEntry("gx");
FeatureIndexEntry f2 = new FeatureIndexEntry("gy");
feature_index.add(f1);
feature_index.add(f2);
System.out.println(feature_index.contains(f1));
}
}
Simple library is great and i already parsed many
different XML from soap servers since last 3 days, but i encountered
boolean attributes with "0" or "1" :
<list mybool1="0" mybool2="1" attr1="attr" attr2="attr">
<page mybool3="1">
...
</page>
<page mybool3="0">
...
</page>
...
</list>
I tried to create this class :
public class Boolean01Converter implements Converter<Boolean>
{
#Override
public Boolean read(InputNode node) throws Exception {
return new Boolean(node.getValue().equals("1"));
}
#Override
public void write(OutputNode node, Boolean value) throws Exception {
node.setValue(value.booleanValue()?"1":"0");
}
}
and implemented it on my object definition :
#Root(name="list")
public class ListFcts
{
#Attribute
#Convert(Boolean01Converter.class)
private Boolean mybool1;
#Attribute
#Convert(Boolean01Converter.class)
private Boolean mybool2;
#Attribute
private int ...
#ElementList(name="page", inline=true)
private List<Page> pages;
public Boolean getMybool1() {
return mybool1;
}
}
But i still get false for every boolean.
[edit]
In fact, when i do this :
#Override
public Boolean read(InputNode node) throws Exception {
return true;
}
i still get false for :
Serializer serial = new Persister();
ListFcts listFct = serial.read(ListFcts.class, soapResult);
if(listFct.getMybool1())
{
//this never happens
}else{
//this is always the case
}
so my Converter has no impact...
Also : how can I attach the converter to the Persister instead of
declaring it on #Attributes hundred times ?
Many thanks in advance !!
[edit2]
i give up with Converter, this is my own solution :
#Root(name="list")
public class ListFcts
{
#Attribute
private int mybool1;
#Attribute
private int mybool2;
public int getMybool1() {
return mybool1;
}
public Boolean isMybool1() {
return (mybool1==1)?true:false;
}
...
}
Your code is using node.getValue() which returns the value (read: contents) of each XML node (the "..." bit in your examples).
What you need is to reading the attribute values, something like node.getAttributeValue("mybool1").equals("1")
i gave up with Converter, I heard about Transform but didn't find how to use it so this is my own basic solution :
#Root(name="list")
public class ListFcts
{
#Attribute
private int mybool1;
#Attribute
private int mybool2;
public int getMybool1() {
return mybool1;
}
public Boolean isMybool1() {
return (mybool1==1)?true:false;
}
...
}
I'm implementing Parcelable class that has another Parcelable insde.
In OuterParcelable class:
#Override
public void writeToParcel(Parcel dest, int flags) {
Bundle tmp = new Bundle();
tmp.putParcelable("innerParcelable", mParcelable);
dest.writeBundle(tmp);
and then:
public OuterParcelable(Parcel parcel) {
super();
Bundle b = parcel.readBundle();
mParcelable = b.getParcelable("innerParcelable");
and:
public OuterParcelable createFromParcel(Parcel in) {
return new OuterParcelable(in);
}
When I recreate object using above code I get:
08-18 17:13:08.566: ERROR/AndroidRuntime(15520): Caused by: android.os.BadParcelableException: ClassNotFoundException when unmarshalling: my.package.InnerParcelable
A clean way to store non-primitive attributes as parcelable, possibly null, values. Use Parcel.writeValue() and readValue(). See comments in code below:
public class MyParcelableClass implements Parcelable {
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeValue(getIntegerAttribute()); // getIntegerAttribute() returns Integer
dest.writeValue(getDoubleAttribute());
dest.writeValue(getMyEnumAttribute()); // getMyEnumAttribute() returns a user defined enum
dest.wrtieValue(getUserClassAttribute()); //UserClass must implement Parcelable in a similar fashion
}
private MyParcelableClass(Parcel in) {
setIntegerAttribute((Integer)in.readValue(null)); //pass null to use default class loader. Ok for Integer, String, etc.
setDoubleAttribute((Double)in.readValue(null)); //Cast to your specific attribute type
setEnumAttribute((MyEnum)in.readValue(null));
setUserClassAttribute((UserClass)in.readValue(UserClass.class.getClassLoader())); //Use specific class loader
}
#Override
public int describeContents() ...
public static final Parcelable.Creator<ParcelableLocationBean> CREATOR ...
}
Works like a charm. writeValue() and readValue() encapsulate the dealing with possible nulls and type detection. From javadoc:
public final void writeValue (Object v) Flatten a generic object
in to a parcel. The given Object value may currently be one of the
following types: null, String, Integer, ... String[],
boolean[], ... Any object that implements the Parcelable protocol. ...
Why are you putting the value into a Bundle? Did you completely implement the parcelable in your class?
Parcelable Skeleton
public MyClass(Parcel in) {
readFromParcel(in);
}
//
// Parcelable Implementation
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeParcelable(aParcelableClass, flags);
}
private void writeObject(Parcel dest, Object obj) {
if (obj != null) {
dest.writeInt(1);
dest.writeValue(obj);
} else {
dest.writeInt(0);
}
}
public void readFromParcel(Parcel in) {
aParcelableClass = in.readParcelable(ParcelableClass.class.getClassLoader());
}
private Object readObject(Parcel in) {
Object value = null;
if (in.readInt() == 1) {
value = in.readValue(null); // default classloader
}
return value;
}
public static final Parcelable.Creator<MyClass> CREATOR = new Parcelable.Creator<MyClass>() {
#Override
public MyClass createFromParcel(Parcel source) {
return new MyClass(source);
}
#Override
public MyClass[] newArray(int size) {
return new MyClass[size];
}
};
I added a few things to make null values more easily dealt with, but the principle is the same. You need the #Override items, constructor, and Creator.
If you're going to read and write a parcelable you will have issues if you specify null as the class loader.