Find a comparable value inside an array property within an Entity - java

How do you find if a property that is an array contains a value, what is available by default to Xodus is txn.find(entityType, propertyName, comparableValue) to find a value, however, what is the best way to find if an array property contains a value. Suppose I have this:
public class EmbeddedArrayIterable implements Serializable, ByteIterable {
}
In which I need to compare if a given value, example "cat", is inside the array. What should be the implementation of EmbeddedArrayIterable as such it will be able to return the Entity to which this "cat" string is in the array of the entity.
As such we can do:
// This property is a `EmbeddedArrayIterable`
// which is a serialized JSON like `["cat","tiger","lion"]`
String propertyName = "keywords";
String comparableValue = "cat";
EntityIterable cats = txn.find(entityType, propertyName, comparableValue);

If you define a custom property type, then you cannot find an entity by only a part of its value. In your case, it makes sense to use ComparableSet value type provided out-of-the-box. Set the property value as a set of items:
final ComparableSet<String> propValue = new ComparableSet<>();
propValue.addItem("cat");
propValue.addItem("tiger");
propValue.addItem("lion");
entity.setProperty("keywords", propValue);
You can then get the value using Entity#getProperty(..), cast to ComparableSet<String> and modify the set if necessary. You can also find the entity by only a single item of the set:
EntityIterable cats = txn.find(entityType, "keywords", "cat");

Related

Update java object's properties by another object of same type

can you give me example how to update values in one object by another object of same type? For example here is my class:
public class MyObj {
private int id;
private String name;
private String phone;
private String address;
// some getters and settters ...
}
And I have another class with that stuff:
private ArrayList<MyObj> objectsList; // list of some objects
public MyObj update ( MyObj newObj ) {
// here I need set new values of properties of newObj to object with same id property in objectsList;
}
Exist some way how to do that without manually setting up all properties?
You have to identify the object in the list by iterating on it or replacing by a Map<String, MyObj>
Exist some way how to do that without manually setting up all
properties?
Sure.
Reflection addresses it but reflection has a cost (it is slower) and it may fail at runtime or give a unexpected behavior.
You can do it manually or better use a library that does the task for you.
But in your case, to handle just 3 fields, it seems an overhead to use reflection.
Just use setters to set them :
MyObj existingObj = ...; // retrieved by a search
existingObj.setName(newObj.getName());
existingObj.setPhone(newObj.getPhone());
existingObj.setAddress(newObj.getAddress());
As alternative, if changing the reference of the object is not a concern, just replace the object actually in the list by which one provided in parameter :
int indexOfTheObject = ...; // retrieved by a search
objectsList.set(indexOfTheObject, newObj);

How hashset remove duplicate entries?

public class Type extends SomeObject implements java.io.Serializable {
private Integer typeId;
private String typeName;
private String typeCode;
}
I am getting data from database using hibernate as Type object. Now my class do not (Nor its parent class) override equals method. SO if i insert all of Type object into a hashset it shouldn't remove duplicates but it is removing duplicate. My question is that how is it able to identify duplicates ?
Inside a Hibernate Session, a given entity only exists once. I.e. if you do
Type type1 = (Type) session.get(Type.class, 42);
Type type2 = (Type) session.get(Type.class, 42);
Type type3 = (Type) session.createQuery("select t from Type t where t.id = 42").uniqueResult();
then type1, type2 and type3 will all be references to a single object. Adding them all in a empty HashSet will thus lead to a HashSet of size 1, because Object.equals() returns true when comparing an object with itself.
if you're class is overriding the hashcode and equals method, the overridden methods are used, or else default methods, the ones present in Object class are used. But hashcode and equals are used in HashSets, Hashmaps, etc.
For default behaviour you can refer to doc
The equals method for class Object implements the most discriminating
possible equivalence relation on objects; that is, for any non-null
reference values x and y, this method returns true if and only if x
and y refer to the same object (x == y has the value true)
As much as is reasonably practical, the hashCode method defined by
class Object does return distinct integers for distinct objects. (This
is typically implemented by converting the internal address of the
object into an integer, but this implementation technique is not
required by the JavaTM programming language.)
Adding how does it find duplicates:
Lets look at hashing first:
Hashing is used to retrieve data quickly. Basically hash function generates an index value (this index value usually refers to a bucket that can store objects), once this index value is generated, it searches for that object inside that particular bucket.
i'd suggest you to look into hashing once
Hashing Wiki
Whenever we add to hashset, the hashcode method is used,it returns an index value, the object is stored in that bucket(the bucket corresponding to that index). when again the same object is being added, the hashcode value will be same, so it refers to the same bucket, now since the object is already present(here equals method is used to check equality amongst objects) in that bucket, it is not added again
class Data {
public Data(String name) {
super();
this.name = name;
}
String name;
}
public class ReadFromFile {
public static void main(String[] args) throws IOException {
Data s = new Data("yo");
HashSet<Data> set = new HashSet<>();
set.add(new Data("hi"));// hi
set.add(new Data("hi"));// hi but has a different address because a new
// object is created
System.out.println("Size before adding s " + set.size());
set.add(s);
set.add(s);// because same object is being added, default hashcode
// generates same value, as it uses address to generate
// hashcode
System.out.println("Size after adding s " + set.size());
}
}
output
Size before adding s 2
Size after adding s 3

How to identify the fields having default values when deserialized using jackson

I have a class Person and I want to deserialize a POJO from a JSON using jackson. Now,
the definition to Person class is something like :
class Person {
int id;
String name;
boolean isOldAge;
boolean hasSenseOfHumor;
.
.
.
}
Now my json is something like :
{
"id" : 1,
"isOldAge" : false
}
Now when I deserialize this into a POJO the values I will get would be :
[id=1,name="",isOldAge=false,hasSenseOfHumor=false]
i.e, the properties not mentioned in json will be assigned their default values.
So my problem lies here. Is there a way I can distinguish isOldAge from hasSenseOfHumor with respect to whether it is mentioned or provided for by the user or not.
Try to change the primitive boolean to the boxing Boolean type. The fields should be initialised with null values then.
If you cannot change field types of the class, then can read your JSON as map in advance as follows mapper.readValue(JSON, Map.class), and then reason about the presence of the boolean fields in the resulting map instance.

Add additional info to arraylist

What is the best way to store one single additional attribute at an arraylist?
Let's say I pass an ArrayList of Objects to a method and get an ArrayList back with an additional flag.
ArrayList<MyObject> list = new ArrayList<MyObject>();
//fill
list = myMethod(list);
And I want to get a boolean for each Object, but I don't want to store it directly in the object.
So data before myMethod: Apple, Banana, Grapefruit
After myMethod: Apple=>true, Banana=>false, Grapefruit=>false.
How can I store that additional attribute when not in the object? What is the best datatype? ArrayList can not do that, right?
You can create a custom wrapper around Object that has a field of type object and a boolean field. This is the best solution as you will be able to choose a meaningful name for the field.
Alternatively you can use the built-in class Pair and create a List<Pair<MyObject, Bool>>.
Use a class with a List<MyObject> field and a List<Boolean> field whose elements are flags parallel to every MyObject added in your List<MyObject>. Since this is too cumbersome, just add the boolean flag in MyObject. If you can't modify the class, extend it and add the boolean flag in your ExtendedMyObject extends MyObject class. If you can't extend it, make a wrapper class of MyObject that has a MyObject field and the boolean flag.
You could separately maintain a Set<MyObject> - membership in the Set would correspond to a true value for that object.
Assuming you used a HashSet, you would need to ensure MyObject implemented equals and hashCode. An alternative would be uniquely identifying each MyObject with a String, Long, etc. and maintaining a Set of those IDs.
I'd recommend just returning a Map with the source object (or name if unique) mapped to the boolean value.
Map<MyObject,Boolean> result = myMethod(list);
or, if name is unique:
Map<String,Boolean> result = myMethod(list);
for (MyObject item : list) {
Boolean result = result.get(item.getName());
if (result) {
...
}
}
If:
MyObject doesn't implement #hashCode (so you may get missed hashes for equal objects)
name isn't unique or
if result were more complex than a Boolean,
then I'd create a wrapper that wraps a MyObject with a result and return a List<MyObjectResult>.
Edit: BTW, I think you're right not to include the Boolean field on MyObject if it is not really a part of that object's state - i.e. if it's a transient result of some operation.
you can extend the ArrayList and give them a new property. For example:
public class MyArrayList<E> extends ArrayList<E>{
private boolean value;
public boolean isValue() {
return value;
}
public void setValue(boolean value) {
this.value = value;
}
}
there you can have all the features from the ArrayList and you have an additinal boolean field.
EDIT:
If your Boolean value has nothing to do with the Originalobject, why not just write a Wrapperclass? There are 2 possibilities to resolve this:
extend your Baseclass MyObject
Write a new class with 2 properties, one for the boolean and the other your instance of MyObject

Get value of type object

I having type object with fields and I want to get the value of specific field on it ,
how should i do that in java?
here i getting specific field type for field id that are related to entityinstance
and now i want to get the value (like 1,2,3 etc)of this specific field "id".
for (Object entityInstance : fromEntityInstances) {
try {
Field declaredField = entityObj.getDeclaredField("id");
I think you're looking for Field.get:
Object value = declaredField.get(entityInstance);
If you know the type of it, you can then cast. For primitives, there are specific methods, such as Field.getInt()
int id = declaredField.getInt(entityInstance);
Once you get the declared field, you can call its get method, like this:
// Don't forget getType() here ---vvv
Field declaredField = entityObj.getType().getDeclaredField("id");
Object res = declaredField.get(entityInstance);
If all objects there are of the same type, you could move the call of getDeclaredField outside the loop to save yourself some CPU cycles.

Categories