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());
Related
I have a class called Varfoo that stores variables. I have another class called Replacement that uses a hashmap to replace the x into 2. With the forget method, it's meant to forget replacing x with 2.
Varfoo x = new VarFoo("x");
Replacement s = new Replacement();
s.put(new VarFoo("x"), new IntFoo(2));
x.applyReplacement(s);
s.forget(x);
Here's the forget method:
public boolean forget(VarFoo var) {
if (var == null) {
throw new NullPointerException();
} else {
if (replacementMap.containsKey(var)) {
replacementMap.remove(var);
return true;
} else {
return false;
}
}
}
It will result to null because I've removed the key itself, not what I intended. How do I revert it back to how it was?
Equals and hashcodes of Varfoo:
#Override
public boolean equals(Object o) {
if (o == null) return false;
if (!(o instanceof VarFoo))
return false;
if (o == this)
return true;
return name.equals(((VarFoo) o).name);
}
#Override
public int hashCode() {
int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
You can make a new implementation of Map, that contains two (e.g.) HashMaps. In normal mode it forwards every operation to map1. This is the original map. map2 is null.
When you make a savepoint, you assign an empty map to map2. get operations now go first to map2 and then, if not found, to map1. put operations go only to map2. When you call forget, you assign again null to map2.
Of course, you must implement all the other methods of the Map interface. But this should be a simple task. Take care of removes, if needed (maybe you will need a Set of removed keys.
Hint: You can use java.util.AbstractMap as a base for your implementation.
i am trying to test singly linked list using Assert.assertEqual(expected, actual) the linked list has a node index and a value. how can i use Assert.assertEquals() to test it.
This is my code
#Test
void nonEmptyTest() throws ListAccessError {
SingleLinkedList<Integer> list = new SingleLinkedList<Integer>();
SingleLinkedList<Integer> expList = new SingleLinkedList<Integer>();
list.add(0,10);
list.add(1,20);
list.add(2,30);
expList.add(0,10);
expList.add(1,20);
expList.add(2,30);
Assert.assertEquals(expList, list);
}
You need to override boolean equals(Object obj) method for you to expect the assert on the actual values of the list.
Here's a sample on how to override
(Note: I don't know your implementation of SingleLinkedList, you can get an idea from the following code and implement accordingly)
#Override
public boolean equals(Object obj) {
if (obj == null)
return false;
SingleLinkedList<Integer> listToCompare = (SingleLinkedList<Integer>) obj;
SingleLinkedList<Integer> thisList = this;
while (listToCompare != null && thisList != null) {
if (!listToCompare.getData().equals(thisList.getData()))
return false;
listToCompare = listToCompare.getNext();
thisList = thisList.getNext();
}
if (listToCompare == null && thisList == null)
return true;
return false;
}
If you want to compare two different objects to find out whether they're equal, your class that defines those objects generally needs to implement the equals() method. Otherwise Java has no way to know what 'equality' is supposed to mean.
That is, your problem is not in the unit test, it's in the class being tested. The
unit test did its job :-)
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);
I was working on overriding .equals() in java for an "Item" class with a Constructor in the form of:
public Item(final String theName, final BigDecimal thePrice, final int theBulkQuantity,
final BigDecimal theBulkPrice) {
myName = Objects.requireNonNull(theName);
myPrice = Objects.requireNonNull(thePrice);
myBulkQuantity = theBulkQuantity;
myBulkPrice = theBulkPrice;
}
using this .equals method:
#Override
public boolean equals(final Object theOther) {
boolean result = false;
if (this == theOther) {
result = true;
}
else if (theOther != null && theOther == this.getClass()) {
final Item other = (Item) theOther;
if ((this.myName.equals(other.myName))
&& (this.myBulkQuantity == other.myBulkQuantity)
&& (this.myPrice.equals(other.myPrice))
&& (this.myBulkPrice.equals(other.myBulkPrice))) {
result = true;
}
}
return result;
}
I'm a new Computer Science student and this is my first attempt at overriding. I would have overlooked this if I had not used JUnit testing using the following:
testItemB = new Item("ItemB", new BigDecimal("5.00"), 5, new BigDecimal("20.00"));
testItemC = new Item("ItemB", new BigDecimal("5.00"), 5, new BigDecimal("20.00"));
and got an assertion error saying that they weren't equivalent. At first glance I am pretty sure that I got everything but do you guys happen to see anything glaring?
In the equals() method you compared the object instance theOther with this.getClass() which will always return false since your are comparing an instance with a class type.
Depending on your use case, you may use
obj1.getClass().equals(obj2.getClass())
or
theOther instanceof Item
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.