I have small issue in arraylist android, let me tell you where i'm facing the issue.
I have a custom contact object, which holds the details about name, contact number and a unique ID. when i query the database i get the list and i will be storing in an ArrayList.
Here how i do
Arraylist<contact> ctlist = new Arraylist(contact);
ctlist = getitemfromDB();
in the next scenario, i do query and get some set of contact object based on certain condition. i get
again contact list objects.
Arraylist<contact> newctlist = new Arraylist(contact);
newctlist = getitemfromDB(condition);
Now, if i pick any object from newctlist and search in ctlist, though the object is present in ctlist
compiler says object not found.
may i know what is wrong with the above way, if i search inside same list i.e if i pick an object from newctlist and search in it, i will get correct expected result.
what would be the problem.
As told by Mitch Wheat, you are trying to compare two different objects. That's because List uses equals method to retrieve specific object. I think you didn't override it in your custom class.
Just implement equals and hashCode methods based on fields in your contact class.
In fact, you should try to always override equals and hashCode methods in classes where equality have a different meaning than just reference equality, e.g. beans. Please have a look there and there. Moreover, if you can, read chapter three from Josh Bloch's "Effective Java" which contains quality rules for those implementations (By the way, read the whole book, it's great).
Please note that there are librairies helping you implementing correctly those (Java7 java.util.Objects, Guava Objects, apache commons EqualsBuilder and HashCodeBuilder)
Be careful as those methods must have very precise mathematical property
Related
I have a class called User.java and the code is as follows,
public abstract class User implements Serializable {
// serialVersionUID
private Integer userId;
private String userName;
private String fullName;
// Constructor()
// Getters and Setters
// equals()
// hashCode()
}
And I have Contact.java class,
public class Contact extends User {
// serialVersionUID
private String phoneNumber;
private String address;
// Constructor()
// Getters and Setters
}
So my question is even User class generated equals and hashcode methods do I need to override it again in the sub class Contact?
And also I am using lombok and the IDE is IntelliJ. I see that when I am generating equals and hashcode through IDE there are to select the template for example,
Default
Apache commons lang 3 like that.
When generating I see that generated hashcode is different for example,
lombok contains different code
Apache commons lang 3 contains different code
So what is the difference between each of those, difference between each generated hascode()?
What can I try to solve this?
Normally, yes, but first you need to think about what equality even means in the context of a User object. For example, I bet you'd consider any User where the ID is equal, to be equal, and there is no need or point to check for equality in the userName or fullName fields, or the phoneNumber field. Possibly you want to check only userName, or only the combination of userId and userName. It's not about the code you want to write, it is about what you consider the definining equality relationship between any two given user objects.
The answer is complicated.
There is no easy answer to this question. Therefore, let's first talk about why you'd even want to add such methods.
What is equals/hashCode for
The point of these two methods is to give you the ability to use instances of your User class (or your Contact class) as keys in a java.util.Map of some sort, or to put them in some java.util.List and have these types actually fulfill what their documentation tells you. If you add objects of a type without equals/hashCode impls to, say, an ArrayList and then call .contains() on this, it won't do what you expected it to. If you try to use them as keys in a map, it won't work right.
Thus, if you aren't planning on putting User objects in lists or maps, then there is no need to fret about any of this stuff. Don't write the methods at all. Move on with life.
Okay, but I do want to do that.
That gets us to..
Then think about what your type actually represents
What does an instance of the Contact class actually represent?
It represents a row in a database (could even be a textfile or a non-SQL based engine); changes to the object will result in changes to the underlying DB, for example.
It represents a contact in a user's address book. Not 'address book' as in 'the data store that the contact app I am writing is using', but 'the actual address book'.
Depending on your answer, the equals/hashCode will be wildly different.
It represents a row in the DB
For SQL-based DB engines, the DB engine has a clear and universally understood definition for equality. If you say that an instance of Contact represents a row in your DB, then it is logical that the equality definition in your java code must match that of SQL, and that definition is simply this: Equal Primary Key? Then they are equal.
PKs can be anything and can be multiple columns, but the vast majority of DB designs use an auto-generated single numeric column for primary key, and given that you have a 'userID' as a field, this sounds like your design.
That means the definition of equality you desire is: equality means: Same userID. But it gets worse: For e.g. hibernate you can make an instance of User and have that object exist in java memory without you ever saving it to the DB yet. That means (for auto-generated primary keys), that the object effectively doesn't have a primary key and for 2 objects without a primary key, even if they are utterly identical in all ways, that thus means they are not equal - and that is such a crazy definition of equality (equal if the userID fields are equal unless the userID fields represent the placeholder value indicating 'not saved to db yet', then not equal, even if they are identical in every way), that no auto-generated tool implements this, you'd have to write it yourself.
It represents an entry in the address book
Then the definition is effectively flipped: that a contact entry has a id is an implementation detail of the database and is the only field in the entire class that is not an actual intrinsic part of the contact as a concept, thus equality is probably best defined as: "Identical, except for the DB id, that does not matter as it is not an intrinsic property of a contact".
Again you need to take some extra actions here; lombok, intellij, eclipse -- all these tools cannot know any of this, and will by default just assume you intend that 2 instances are equal only if every field is equal.
Um.. how do I choose?
Well, go back to what equals/hashCode is for: To make instances of this stuff function as keys in maps and for contains and such to give proper answers when these instances are stored in java lists. So, what do you want to occur if you store 2 separate instances of Contact into a list, where somehow they both have the same ID, but a different username value? Depending on your answer, you know which of the two interpretations are correct.
Why are these tools generating different impls of hashCode?
They don't. Not really. The point of hashCode is very simple:
If any two given objects have different hashcodes, they cannot possibly be equal.
That's it. That's all it means. Two objects with equal hashcodes don't need to be equal (you'd have to invoke a.equals(b) to find out), but two objects with non-equal hashcodes are not equal, and there is no need to invoke a.equals(b) to find out. This is not enforced by java at all, but you're supposed to write it that way (ensure that if 2 objects have non-equal hashcode, that they cannot be equal). If you fail to do so, instances of your classes will do bizarre things when used as e.g. keys in hashmaps.
There are many ways to write an algorithm that leads to this effect. This explains why there are small differences. But, they are all about equally effective (they generate different hashcodes for known different objects about as efficiently, and the hashCode method runs about equally performant, for all of these different tools).
Subtyping
Subtyping is extremely complicated in regards to equality. That's due to the rules as documented in Object's equals and hashCode javadoc. This answer is very long already so I won't get into why, so you'll just have to do some web searching or take my word for it. However, asking tools to auto-gen equality/hashCode impls in the face of a type hierarchy is very tricky.
It sure sounds like you want to lock down what equality (and therefore hashcode) means at the class User level (namely: equality is defined by having the same userID. Perhaps the same username if that sounds more applicable to your situation. But no more than that), in which case you should write these methods yourself, and they should be:
public final boolean equals(Object other) {
if (other == this) return true;
if (this.userId == null) return false;
if (!(other instanceof User) return false;
return this.userId.equals(((User) other).userId);
}
public final int hashCode() {
return userId == null ? System.identityHashCode() : 61 * userId.intValue();
}
Why?
These define equality by way of 'both have a userID, and they are equal'.
They are consistent with the rules (such as: any 2 equal objects will neccessarily have equal hashcodes).
They are simple.
They are 'final', because otherwise this gets incredibly complicated, and you can't allow subtypes to redefine equality on you, that can't work, due to the rule that a.equals(b) must match b.equals(a).
Why 61? It's just an arbitrarily chosen prime number. Pretty much any number would do; an arbitrary prime is very very very slightly more efficient in exotic cases.
Actually I want the other definition
Then use lombok (disclaimer: I am a core contributor there, so this is me rating myself), because it has the best equals implementation, and you won't have to look at the code or maintain it. Mark your userId field with the #EqualsAndHashCode.Exclude annotation, and mark the Contact class with #EqualsAndHashCode(callSuper = true), and User with #EqualsAndHashCode (or something that includes that, like #Value) - the callSuper is needed to tell lombok that the parent class has a lombok-compatible equals implementation.
What would you use if you wanted to pass a list of options into a function?
For example, if you have an interface to a server:
public interface Server {
public void authUser(String username, String password, <xyz> options);
}
What structure would use use for to pass a set of options? Something like a HashMap?
The reason I'm saying that it comes from tunnel vision is because I feel that this goes against Java standards. Java has method overloading. So if I get flames for raising the question I understand. But overall, maybe in different cases, would you ever pass bulk data in some collection and, if yes, which one?
Option1 : If you are choosing any collections like List or Set these are specific to an object . I mean,
Lets Assume, Set sets = new HashSet();
If I want 5 Object of different different class having no relationship to be send, then It would be very difficult to recognize that which Object is belong to which class while Iteration. So, I wont recommend Collections.
Option2 : If you are choosing Map, the same above problem may occurs while getting the Object Dynamically. So, This Options is also not recommended.
Option3 :
Why cann't you create your own DTO and in that DTO place your reqyired datastructure and pass it over.
If you want 5 different Object to be pass then, you can pass. If all are of same type then you may use Collection or array or Variable Arguement based on your scenerio.
I think anything Serializable is exactly the thing. If you can serialize the object, then you can pass (store, transmit...) it, passing it's properties in bulk. What format of serialized data to choose, is another question.
It depends on the data you want to pass.
You can use a map(hashmap) if you are passing key-value pairs.
If it is just a list of diffrent object, you can use List(ArrayList)
Other option is to create DTO(data transfer object) with getter and setter methods.
You may want to take a look at VARARGS feature that was introduced in JAVA5.
I'd suggest a Map [HashMap] as you can then access the argument values via their Keys.
Hey im making a store for student details and i wanted some opinions on which collection to use. The store will have details such as name, number, address and email. The store will then be printed to a text file where i can load, save, edit and delete the details in the text file. I have never done this before and i do not no if there is any restrictions to file I/O when using collections. So i would really appreciate the comments. Thanks in advance.
If I were at your place,
then i would have created a bean class say Student and for collection ArrayList<Student> student = new ArrayList<Student>(); and as ArrayList is serialized so no issue for disk writing and a class for all IO operations.
For sorting ArrayList by object property look
Unless some special "fast location" capabilities are required, such as search by last name or by student ID, a list would be an appropriate collection to use.
List<Student> students = new ArrayList<Student>();
If you do need to organize your students by some attribute, say, by student ID, consider using LinkedHashMap:
Map<String,Student> studentById = new LinkedHashMap<String,Student>();
LinkedHashMap gives you a predictable order of iteration. You could use a regular HashMap<K,V>, but the order of iteration will be arbitrary. Finally, you could use a TreeMap<K,V>, which would base the order of iteration on the ordering of the keys.
Well if it has to be serializable, i.e. meaning you can write it to disk, you can use a List. Now before anyone screams you can't serialize a List that is correct, but you also cannot instantiate a List either. Since we know all known subclasses of List are serializable you can safely cast. In terms of how to store the data List<Student> should be just fine.
EDIT
There seems to be some confusion here. In Object Oriented languages we know that the is-a relationship holds true for objects specified in a hierarchy. So in the Java API we have an interface called List this interface has classes that implement it ArrayList for instance. This puts ArrayList in the hierarchy of List. Since ArrayList implements Serializable and we know that you cannot instantiate an object marked with the keyword interface (in Java). We can use casting to Serialize any known implementation of List. The reason why this will work is that the implementation (i.e. concrete object) that is passed around is guaranteed to be serializable.
In the simplest case a java.util.List will do exactly what you want. However, if you want to be able to find entries in the collection quickly ( to support your update requirements ), you should also probably look at java.util.Map. Map allows you to navigate quickly to a particular record without having to iterate over the entire collection, whereas with a List you'd have to look at every student in the collection in turn until you find the one you are interested in.
I have two sets both containing the same object types. I would like to be able to access the following:
the intersection of the 2 sets
the objects contained in set 1 and not in set 2
the objects contained in set 2 and not in set 1
My question relates to how best to compare the two sets to acquire the desired views. The class in question has numerous id properties which can be used to uniquely identify that entity. However, there are also numerous properties in the class that describe the current status of the object. The two sets can contain objects that match according to the ids, but which are in a different state (and as such, not all properties are equal between the two objects).
So - how do I best implement my solution. To implement an equals() method for the class which does not take into account the status properties and only looks at the id properties would not seem to be very true to the name 'equals' and could prove to be confusing later on. Is there some way I can provide a method through which the comparisons are done for the set methods?
Also, I would like to be able to access the 3 views described above without modifying the original sets.
All help is much appreciated!
(Edit: My first suggestion has been removed because of an unfortunate implementation detail in TreeSet, as pointed out by Martin Konecny. Some collection classes (e.g. TreeSet) allow you to supply a Comparator that is to be used to compare elements, so you might want to use one of those classes - at least, if there is some natural way of ordering your objects.)
If not (i.e. if it would be difficult to implement CompareTo(), while it would be simpler to implement HashCode() and Equals()), you could create a wrapper class which implements those two functions by looking at the relevant fields from the objects they wrap, and create a regular HashSet of these wrapper objects.
Short version: implement equals based on the entity's key, not state.
Slightly longer version: What the equals method should check depends on the type of object. For something that's considered a "value" object (say, an Integer or String or an Address), equality is typically based on all fields being the same. For an object with a set of fields that uniquely identify it (its primary key), equality is typically based on the fields of the primary key only. Equality doesn't necessarily need to (and often shouldn't) take in to consideration the state of an object. It needs to determine whether two objects are representations of the same thing. Also, for objects that are used in a Set or as keys in a Map, the fields that are used to determine equality should generally not be mutable, since changing them could cause a Set/Map to stop working as expected.
Once you've implemented equals like this, you can use Guava to view the differences between the two sets:
Set<Foo> notInSet2 = Sets.difference(set1, set2);
Set<Foo> notInSet1 = Sets.difference(set2, set1);
Both difference sets will be live views of the original sets, so changes to the original sets will automatically be reflected in them.
This is a requirement for which the Standard C++ Library fares better with its set type, which accepts a comparator for this purpose. In the Java library, your need is modeled better by a Map— one mapping from your candidate key to either the rest of the status-related fields, or to the complete object that happens to also contain the candidate key. (Note that the C++ set type is mandated to be some sort of balanced tree, usually implemented as a red-black tree, which means it's equivalent to Java's TreeSet, which does accept a custom Comparator.) It's ugly to duplicate the data, but it's also ugly to try to work around it, as you've already found.
If you have control over the type in question and can split it up into separate candidate key and status parts, you can eliminate the duplication. If you can't go that far, consider combining the candidate key fields into a single object held within your larger, complete object; that way, the Map key type will be the same as that candidate key type, and the only storage overhead will be the map keys' object references. The candidate key data would not be duplicated.
Note that most set types are implemented as maps under the covers; they map from the would-be set element type to something like a Boolean flag. Apparently there's too much code that would be duplicated in wholly disjoint set and map types. Once you realize that, backing up from using a set in an awkward way to using a map no longer seems to impose the storage overhead you thought it would.
It's a somewhat depressing realization, having chosen the mathematically correct idealized data structure, only to find it's a false choice down a layer or two, but even in your case your problem sounds better suited to a map representation than a set. Think of it as an index.
Best way to describe this is explain the situation.
Imagine I have a factory that produces chairs. Now the factory is split into 5 sections. A chair can be made fully in one area or over a number of areas. The makers of the chairs add attributes of the chair to a chair object. At the end of the day these objects are collected by my imaginary program and added into X datatype(ArrayList etc).
When a chair is added it must check if the chair already exists and if so not replace the existing chair but append this chairs attributes to it(Dont worry about this part, Ive got this covered)
So basically I want a structure than I can easily check if an object exists if not just straight up insert it, else perform the append. So I need to find the chair matching a certain unique ID. Kind of like a set. Except its not matching the same object, if a chair is made in three areas it will be three distinct objects - in real life they all reperesent the same object though - yet I only want one object that will hold the entire attribute contents of all the chairs.
Once its collected and performed the update on all areas of the factory it needs iterate over each object and add its contents to a DB. Again dont worrk about adding to the DB etc thats covered.
I just want to know what the best data structure in Java would be to match this spec.
Thank you in advance.
I'd say a HashMap: it lets you quickly check whether an object exists with a given unique ID, and retrieve that object if it does exist in the collection. Then it's simply a matter of performing your merge function to add attributes to the object that is already in the collection.
Unlike most other collections (ArrayList, e.g.), HashMaps are actually optimized for looking something up by a unique ID, and it will be just as fast at doing this regardless of how many objects you have in your collection.
This answer originally made reference to the Hashtable class, but after further research (and some good comments), I discovered that you're always better off using a HashMap. If you need synchronization, you can call Collections.synchronizedMap() on it. See here for more information.
I'd say use ArrayList. Override the hashcode/equals() method on your Chair object to use the unique ID. That way you can just use list.contains(chair) to check if it exists.
I'd say use an EnumMap. Define an enum of all possible part categories, so you can query the EnumMap for which part is missing
public enum Category {
SEAT,REST,LEGS,CUSHION
}