Below are two list Some1 and Some which actually has same object data but different in order of elements in object and order of objects in array. My concern is below has to return true. Please favour
List<Some> lome1=new ArrayList<Some>();
Some some1 = new Some();
some1.setTime(1000);
some1.setStartTime(25);
some1.setEndTime(30);
lome1.add(some1);
Some some2 = new Some();
some2.setStartTime(125);
some2.setEndTime(130);
some2.setTime(100);
lome1.add(some2);
List<Some> lome2=new ArrayList<Some>();
Some some3 = new Some();
some3.setStartTime(125);
some3.setEndTime(130);
some3.setTime(100);
lome2.add(some3);
Some some = new Some();
some.setStartTime(25);
some.setTime(1000);
some.setEndTime(30);
lome2.add(some);
Attempts which failed due to order:
With deepEquals:
if(Arrays.deepEquals(lome1.toArray(),lome2.toArray()) ){
System.out.println("equal");
}
else {
System.out.println("not equal");
}
With hashset, both gave different hash value though data is same
if(new HashSet<>(lome1).equals(new HashSet<>(lome2)) ){
System.out.println("equal");
}
else {
System.out.println("not equal");
}
Check if object is contained in another
boolean x=true
for(Some d: lome1) {
if(!lome2.contains(d)) {
x = false;
}
}
if(x){
System.out.println("equal");
}
else {
System.out.println("not equal");
}
First Override hashcode and equals for Some Object, It may look like this,
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Some that = (Some) o;
return startTime == that.startTime &&
endTime == that.endTime &&
time == that.time
}
#Override
public int hashCode() {
return Objects.hash(startTime, endTime, time);
}
Once equals and Hashcode is set then different object with same values will give the same hashcode thus .equals() will return true
Now for the list use
list1.containsAll(list2) && list2.containsAll(list1);
Comparing the two lists as HashSets is probably the best approach, since that works irrespective of the order.
However, your HashSet comparison is dependent on you implementing the equals() and hashCode() functions in your "Some" class. You've not provided the source for that, so I'm guessing you've missed that. Without overriding those methods in your class, the JRE doesn't know that two Some objects are the same or not.
I'm thinking something like this:
#Override
public int hashCode() {
return getTime() + getStartTime() + getEndTime();
}
#Override
public boolean equals(Object o) {
if (o instanceof Some) {
Some other = (Some)o;
if (getTime() == other.getTime()
&& getStartTime() == other.getStartTime()
&& getEndTime() == other.getEndTime()) {
return true;
}
}
return false;
}
The containsAll() API provided by java collection.
lome1.containsAll(lome) should do the trick.
For Java 1.8+ you could check that each element of first list is in the second and vice versa:
boolean equals = lome1.stream().allMatch(e -> lome2.contains(e)) &&
lome2.stream().allMatch(e -> lome1.contains(e));
Do Something like this
List<User> list = new ArrayList<>();
list.add(new User("User","20"));
list.add(new User("Some User","20"));
List<User> list1 = new ArrayList<>();
list1.add(new User("User","20"));
list1.add(new User("Some User","20"));
List<User> storeList = new ArrayList<>();
for (User user: list){
for (User user1:list1){
if (user.getName().equals(user1.getName()) && user.getAge().equals(user1.getAge()))
storeList.add(user);
}
}
boolean check = !storeList.isEmpty();
//OR
check = storeList.size() == list.size();
System.out.println(check);
Related
My equals() method:
Here when in second if statement when my my object is null for example, I should return false but for some reason my code fails to do so. Any help?
public boolean equals(Prof o) {
boolean res = false;
if(this == o) {
res = true;
}
if(o == null || this.getClass() != o.getClass()) {
res = false;
}
Prof other = (Prof) o;
if(this.year == other.year) {
if(this.id.equals(other.id)) {
res = true;
}
}
else {
res = false;
}
return res;
}
Test Case:
public void test02_ProfEqualHash() {
Prof p1 = new Prof("John S Lee", "yu213", 5);
assertTrue(p1.equals(p1));
Prof p0 = null; // null
assertFalse(p1.equals(p0)); // my equals() implementation fails here
Date d = new Date();
String s = "Hello";
assertFalse(p1.equals(d));
assertFalse(p1.equals(s));
Prof p2 = new Prof("John L", "yu213", 5);
assertTrue(p1.equals(p2));
assertTrue(p1.hashCode() == p2.hashCode());
assertTrue(p2.equals(p1));
Prof p3 = new Prof("John S Lee", "yu203", 5);
assertFalse(p1.equals(p3));
//assertNotEquals(p1.hashCode(), p3.hashCode());
Prof p4 = new Prof("Tracy T", "yu053", 2);
assertFalse(p1.equals(p4));
//assertNotEquals(p1.hashCode(), p4.hashCode());
Prof p5 = new Prof("John S Lee", "yu213", 8);
assertFalse(p1.equals(p5));
//assertTrue(p1.hashCode() != p5.hashCode());
}
First of all, in order to correctly override Object's equals(), the method signature should be:
public boolean equals(Object o) {
....
}
Even though your test code calls your equals() method, JDK classes that expect Object's equals() signature will not.
In addition, you should return false immediately when you find that the o argument is null, in order not to access it later in your method (which would cause NullPointerException).
A correct implementation can look like this:
public boolean equals (Object o)
{
if (this == o) {
return true;
}
if (o == null || !(o instanceof Prof)) {
return false;
}
Prof other = (Prof) o;
return this.year == other.year && this.id.equals(other.id);
}
In Java Object class is the superclass of every class. So in order to override the equal method defined in the Object class, you need to follow the same method definition, which is:
#Override
public boolean equals(Object other) {
// here goes your implementation class
}
Since your definition of equals has Prof as an argument, hence you are not actually overriding the Object equals method.
For more information on the equals contract, you can read Item10 from Effective Java book by Josh Bloch.
Also, if your class has an equals method, then you should always define the hashCode implementation as well. Here is the implementation of this method:
#Override
public int hashCode() {
return Objects.hash(year, id);
}
My class:
public class UserProgressModel {
private String email;
public UserProgressModel(String pEmail) {
super();
this.email = pEmail;
}
#Override
public boolean equals(Object x) {
if (x != null && x instanceof UserProgressModel
&& ((UserProgressModel) x).email.equals(this.email) == true) {
return true;
}
if (x != null && x instanceof String
&& x.equals(this.email) == true) {
return true;
}
return false;
}
#Override
public int hashCode() {
int hash = 7;
hash = 17 * hash + (this.email != null ? this.email.hashCode() : 0);
return hash;
}
}
And after putting some objects via gson:
UserProgressModel[] userProgressArray;
List<UserProgressModel> retUserProgress = new ArrayList<>();
userProgressArray = gs.fromJson(fileContents,
new TypeToken<UserProgressModel[]>() {
}.getType());
for (UserProgressModel ele : userProgressArray) {
if (ele != null) {
retUserProgress.add(ele);
}
}
I am unable to get true for the following code:
retUserProgress.contains("test#test.com");
I looped thru the array to verify that one object has the email.
Am I doing right? I think I have overridden the equals & hashcode.
Your equals implementation is incorrect. If you look at the contract for equals the implementation must be symmetric:
... for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.
In your case you have a list of UserProgressModel objects, but you are trying to compare against a String. While you've implemented UserProgressModel.equals(String) you would still need to have String.equals(UserProgressModel) return the correct result. Since you cannot do that this implementation will never work in all cases. What you should do is two things:
Remove the check in equals for String because it will never work.
Use a mock object to check in the collection:
retUserProgress.contains(new UserProgressModel("test#test.com"));
As long as your equals method is correct within your own type (UserProgressModel.equals(UserProgressModel)) this should fix your issue.
You cannot check if the retUserProgress contains e-mails because it does not. The ArrayList contains objects of Class: UserProgressModel, thus you can check if the ArrayList contains a 'UserProgressModel'.
What you would like to do is the following
private boolean containsEmail(List<UserProgressModel> retUserProgress, String email) {
boolean result = false;
for (UserProgressModel object : retUserProgress) {
if (object.equals(email))
result = true;
}
return result;
}
And the call the method like so:
containsEmail(retUserProgress, "test#test.com"); //This will return a true or false, depending if the ArrayList retUserProgress contains the email
i have tested your code in ideone
and it's working
true
UserProgressModel model=new UserProgressModel("test#test.com");
System.out.print(model.equals("test#test.com"));
false
UserProgressModel model=new UserProgressModel("test#test.com");
System.out.print(model.equals("test#test.co"));
try to compare with new object
retUserProgress.contains(new UserProgressModel("test#test.com"))
result
if you don't wanna compare with a new UserProgressModel you need to create your own list type that when it compare two object (UserProgressModel,string) it creates a new UserProgressModel and pass that email for it
I have a Set and I will check if an Object with the same property still exists. My first approach was to iterate over the list and check but I guess there is a better approach in Java 8. Does anyone have any suggestion how to check this in an elegant way?
final Set<UserSelected> preparedUserSelected = new HashSet<>();
UserSelected userSelected1 = new UserSelected();
userSelected1.setInstitutionId("1");
userSelected1.setUserId("1");
userSelected1.setChatMessageFilter(ChatMessageFilterEnum.TYP2);
UserSelected userSelected2 = new UserSelected();
userSelected2.setInstitutionId("2");
userSelected2.setUserId("2");
userSelected2.setChatMessageFilter(ChatMessageFilterEnum.TYP1);
UserSelected userSelected3 = new UserSelected();
userSelected3.setInstitutionId("3");
userSelected3.setUserId("3");
userSelected3.setChatMessageFilter(ChatMessageFilterEnum.TYP2);
preparedUserSelected.add(userSelected1);
preparedUserSelected.add(userSelected2);
preparedUserSelected.add(userSelected3);
UserSelected userSelectedToCheck = new UserSelected();
userSelectedToCheck.setInstitutionId("2");
userSelectedToCheck.setUserId("2");
userSelectedToCheck.setChatMessageFilter(ChatMessageFilterEnum.TYP1);
boolean contains = false;
for (final UserSelected userSelected : preparedUserSelected) {
if (userSelectedToCheck.getInstitutionId().equals(userSelected.getInstitutionId())
&& userSelectedToCheck.getUserId().equals(userSelected.getUserId())
&& userSelectedToCheck.getChatMessageFilter() == userSelected.getChatMessageFilter())
contains = true;
}
System.out.println("contains: " + contains);
You need to properly implement equals and hashCode methods in your UserSelected class. After that you can easily check the existence with preparedUserSelected.contains(userSelectedToCheck).
Here's sample implementation of equals/hashCode for your class:
#Override
public int hashCode() {
return Objects.hash(getUserId(), getInstitutionId(), getChatMessageFilter());
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null || getClass() != obj.getClass())
return false;
UserSelected other = (UserSelected) obj;
return Objects.equals(getChatMessageFilter(), other.getChatMessageFilter()) &&
Objects.equals(getInstitutionId(), other.getInstitutionId()) &&
Objects.equals(getChatMessageFilter(), other.getChatMessageFilter());
}
Try this anyMatch of Lambda Expression(Java 8).
Returns whether any elements of this stream match the provided predicate. May not evaluate the predicate on all elements if not necessary for determining the result. If the stream is empty then false is returned and the predicate is not evaluated.
boolean isExist = preparedUserSelected.stream()
.anyMatch(userSelected -> userSelected.getInstitutionId().equalsuserSelected.getInstitutionId());
I have a class
MyData
and its object
myData
In that Class MyData .. there are multiple fields
like
int id
String name
String desc
etc ..
Now i have two objects of this class ..
Is it possible to check that if the data of these two object are all the same , Like both objects have the same Id ,same Name ,same Desc ... Without checking each and every field of this object ..(i.e without checking the id,name,desc of Each object myself) As there are dozens of fields of this object .
I am using JAVA with GWT
Some implementation i came across.. Not sure if this is some thing possible .valid
private static String oldSequence = "";
boolean changed(TestSequence sequence) {
String newSequence = serializeToString(sequence);
boolean changed = !newSequence.equals(oldSequence);
oldSequence = newSequence;
return changed;
}
private static byte[] serialize(Object obj) throws IOException {
ByteArrayOutputStream b = new ByteArrayOutputStream();
ObjectOutputStream o = new ObjectOutputStream(b);
o.writeObject(obj);
return b.toByteArray();
}
private static String serializeToString(Object obj) {
try {
return new String(serialize(obj));
} catch (Exception ex) {
return "" + ex;
}
}
Thanks
You should override hashCode() and equals() method. you can generate these from IDE.
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof MyData)) return false;
MyData myData = (MyData) o;
if (id != myData.id) return false;
if (!desc.equals(myData.desc)) return false;
if (!name.equals(myData.name)) return false;
return true;
}
#Override
public int hashCode() {
int result = id;
result = 31 * result + name.hashCode();
result = 31 * result + desc.hashCode();
return result;
}
Now you can compare the objects. That's it.
Conventional way is to override equals and hashCode methods. Java standard libraries, for instance Map s, List s, Set s use the equals and hashCode functions for equality testing. The code below also null-safe;
Here is the code for your case;
public class MyData {
int id;
String name;
String desc;
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MyData myData = (MyData) o;
if (id != myData.id) return false;
if (desc != null ? !desc.equals(myData.desc) : myData.desc != null) return false;
if (name != null ? !name.equals(myData.name) : myData.name != null) return false;
return true;
}
#Override
public int hashCode() {
int result = id;
result = 31 * result + (name != null ? name.hashCode() : 0);
result = 31 * result + (desc != null ? desc.hashCode() : 0);
return result;
}
}
and you can test the equality by;
....
Mydata d1 = new...
Mydata d2 = new...
boolean areTheyEqual = d1.equals(d2);
However if you are not allowed to make a compare field by field then you can use byte arrays, there is no need to convert them to strings.
.....
public boolean equals(Object other){
if (this == other) return true;
if (other == null || getClass() != other.getClass()) return false;
byte[] bytesThis = serialize(this);
byte[] bytesOther = serialize(other);
if(bytesOther.length != bytesThis.length) return false;
return Arrays.equals(bytesThis, bytesOther);
}
public static byte[] serialize(Object obj) throws IOException {
ByteArrayOutputStream b = new ByteArrayOutputStream();
ObjectOutputStream o = new ObjectOutputStream(b);
o.writeObject(obj);
return b.toByteArray();
}
...
GWT doesn't make a difference to your requirement.
There is no direct way.
You have to define your equality to check weather they are equal or not. That is overriding equals() method.
#Override
public boolean equals(Object obj) { ...
Before doing:Right way to implement equals contract
Like everyone else is saying, you should override the equals() and hashCode() methods.
Note that you don't have to do this manually. In Eclipse you can simply click on Source/generate hashCode() and equals() and it will do the work for you. I am sure other IDEs have similar feature as well.
If you don't want to add any more code when you add a new field, you can try iterating over fields.
You said "Without checking each and every field of this object ..(i.e without checking the id,name,desc of Each object myself) ", I couldn't figure out whether you don't want to check for each field for equality, or don't want to WRITE a check for each field for equality. I assumed the latter since you tried to add an equality comparison method by using bytewise checks.
Anyways, the code to check each field follows. You can copy/paste to any object. If, in the future, you want some fields to be checked and some not, you can use annotations.
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MyData myData = (MyData) o;
Field[] fields = this.getClass().getDeclaredFields();
for(Field field:fields){
Object o1 = null;
Object o2 = null;
try {
o1 = field.get(this);
o2 = field.get(o);
} catch (IllegalAccessException e) {
return false;
}
if(o1 == null && o2 != null) return false;
if(o2 == null && o1 != null) return false;
if(o2 == null && o1 == null) continue;
if(!o2.equals(o1)) return false;
}
return true;
}
No.
You have to override the equals() method and compare the objects in that.
Override the equals method of the object in MyData and check the fields independently.
Serialize your objects and compare the results!
You just should be wise in selection of your serialization method.
Override hashCode() and equals() methods
hashCode()
This method provides the has code of an object.
Basically the default implementation of hashCode() provided by Object is derived by mapping the memory address to an integer value. If look into the source of Object class , you will find the following code for the hashCode.
public native int hashCode();
It indicates that hashCode is the native implementation which provides the memory address to a certain extent. However it is possible to override the hashCode method in your implementation class.
equals()
This method is used to make equal comparison between two objects. There are two types of comparisons in Java. One is using “= =” operator and another is “equals()”. I hope that you know the difference between this two. More specifically the .equals() refers to equivalence relations. So in broad sense you say that two objects are equivalent they satisfy the equals() condition.
I have 2 classes.
public class klass1 {
String bir;
String myID;
klass1(String bir, String myID)
{
this.bir=bir;
this.myID=myID;
}
}
.
import java.util.*;
public class dd {
public static void main(String[] args) {
ArrayList<Object> ar=new ArrayList();
ar.add(new klass1("wer","32"));
ar.add(new klass1("das","23"));
ar.add(new klass1("vz","45"));
ar.add(new klass1("yte","12"));
ar.add(new klass1("rwwer","43"));
ar.remove(new klass1("vz","45"));//it's not worked!!!
System.out.println(ar.size());
}
}
What I want is removing or getting an object from array list with object's second attribute. How can I do that? Is there an easy way for it?
Just implement the equals method in the class Klass1.
public class Klass1 {
String bir;
String myID;
Klass1(String bir, String myID)
{
this.bir=bir;
this.myID=myID;
}
public boolean equals(Object o){
if(o instanceof Klass1)
return ((Klass1)o).myID.equals(myID);
else
return false;
}
}
Its because you are trying to delete a new object which isnt in the arraylist. When you use new klass1("vz","45") you are creating a new instance of this class which isnt in the arraylist.
What the system does internally is to compare those classes using equals. Why this doesn't work is explained in the following code:
Object o1 = new Object();
Object o2 = new Object();
System.out.println(o1 == o2); // false, obviously
System.out.println(o1.equals(o2)); // false
System.out.println(o1); // java.lang.Object#17046822
System.out.println(o2); // java.lang.Object#22509bfc
You can tell by the number following the # that these objects have a different hash values, and this is what the equals function of Object does check.
This is relevant for your klass, because unless you overwrite equals, you will use the equals of Object. And if you implement equals you should always implement hashcode as well. Because both tell you something about whether or not two objects are the "same", and if the one says something else than the other, some part of your code might get confused.
How to properly implement equals for your class:
#Override
public int hashCode() {
int hash = 7;
hash = 17 * hash + Objects.hashCode(this.bir);
hash = 17 * hash + Objects.hashCode(this.myID);
return hash;
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final klass1 other = (klass1) obj;
if (!Objects.equals(this.bir, other.bir)) {
return false;
}
if (!Objects.equals(this.myID, other.myID)) {
return false;
}
return true;
}
This can be done in most IDEs btw with a shortcut (i.E. alt-insert in Netbeans). Note that I did this in Java 7 using Objects. If you are in Java 6, you need to manually type(a == b) || (a != null && a.equals(b)); with the appropriate objects to compare.
Creating a proper hashcode is not always trivial, for more complex objects you might want to read a bit about hashcodes first. For simple objects: multiply primes with something.
The equals method is usually trivial, it is just important to first check for null and for class equality. This is often forgotten by programmers and a common source for NullPointerExceptions and ClassCastExceptions.