Two same arrays but contains method not working - java

I have a SmsClass:
public class SmsClass {
private String numberInside;
private String name;
public SmsClass( String numberInside ,String name) {
this.numberInside = numberInside;
this.name = name;
}
and I try to make two same ArrayList of this class:
SmsClass SmsClass3 = new SmsClass("name" , "19");
SmsClass SmsClass4 = new SmsClass("name" , "19" );
ArrayList<SmsClass> c1 = new ArrayList<>();
ArrayList<SmsClass> c2 = new ArrayList<>();
c1.add(SmsClass1);
c1.add(SmsClass2);
c2.add(SmsClass3);
c2.add(SmsClass4);
I have problem with .contains method . When I run this code :
for(int i = 0 ; i < c1.size() ; i++){
if (c1.contains(c2.get(i))) {
System.out.println("victory");
}
}
I have same arrays but nothing found.

You should override this equals method like this in SmsClass;
public class SmsClass {
private String numberInside;
private String name;
public SmsClass(String numberInside, String name) {
this.numberInside = numberInside;
this.name = name;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof SmsClass)) return false;
SmsClass smsClass = (SmsClass) o;
if (numberInside != null ? !numberInside.equals(smsClass.numberInside) : smsClass.numberInside != null)
return false;
return name != null ? name.equals(smsClass.name) : smsClass.name == null;
}
}
Just an idea, you can check easily without a for loop equations of two list .
c1.removeAll(c2);
if (c1.isEmpty()) {
System.out.println("victory!");
}

You must define equals in your Object.
Something like this:
public class SmsClass {
private String numberInside;
private String name;
public SmsClass( String numberInside ,String name){
this.numberInside = numberInside;
this.name = name; }
public boolean equals(Object obj) {
if(obj instanceof SmsClass ) {
SmsClass smsObj = (SmsClass)obj;
if(smsObj.getNumberInside() == this.getNumberInside() &&
smsObj.getName() == this.getName())
return true;
}
return false;
}
}

You have not defined equals (and implicitly hashCode), thus contains can not compare your Objects. In case you do not override those both method: Object::equals will be used (which just uses reference comparison, via ==) and hashCode (in java-8) will be computed as a pseudo-random number (based on Marsaglia XOR shift algorithm).

Variable names should not start with capital letter as recommendation.
Also, you added SmsClass1, and SmsClass2 to c1 list, while adding SmsClass3, and SmsClass4 to c2 list. Although, smsClass1 and smsClass3 have same values in their fields, they are stored on different part of memory. ArrayList.contains() method check equality according to elements' references(where they placed in memory).
SmsClass SmsClass3 = new SmsClass("name" , "19");
SmsClass SmsClass4 = new SmsClass("name" , "19" );
ArrayList<SmsClass> c1 = new ArrayList<>();
ArrayList<SmsClass> c2 = new ArrayList<>();
c1.add(SmsClass1);
c1.add(SmsClass2);
c2.add(SmsClass3);
c2.add(SmsClass4);

Related

If i compared the instance variable of class with the object what will it compare?

public class Notepad {
private String name;
private int year;
public Notepad(String name, int year) {
this.name = name;
this.year = year;
}
public boolean equals(Object object) {
if (object == null || this.getClass() != object.getClass()) {
return false;
}
if (object == this) {
return true;
}
Notepad compared = (Notepad) object;
return this.name.equals(compared);
}
}
Notepad basics = new Notepad("Equals basics", 2000);
Notepad advanced = new Notepad("Equals advanced", 2001);
System.out.println(basics.equals(basics));
System.out.println(basics.equals(advanced));
System.out.println(basics.equals(new Notepad("Equals basics", 2000)));
System.out.println(basics.equals(new Notepad("Equals basics", 2001)));
In the above code at the last two lines when i compare the basics object it returns false.In the equals method when i check this.name.equals(compared) what does it actually compares?
return this.name.equals(compared);
Here you are comparing name field of NotePad object with the object of NotePad.
You should compare with the name field of the compared
return this.name.equals(compared.name);
What happened when compare String with NotePad object ?
Doc for String equals method
Compares this string to the specified object. The result is true if
and only if the argument is not null and is a String object that
represents the same sequence of characters as this object.
So as comparing Notpad object is not a String object it will return false.
this.name will not be compared to anything in the Notepad object. Similarly to your Notepad.equals method, the String.equals will check if the object supplied is not null first, and then if it is of an appropriate class, that is a String. A Notepad is not a String so here the comparison ends. No members of the given object are tested.
this.name returns String which is an object.
You are comparing this.name with object compared of class Notepad. If you want to compare the names use:
this.name.equals(compared.name)
If you want to have the same condition return true, override equals() and hashCode() methods of Project class.
equals() returns true only if int value returned by hashCode()method for both the objects is equal.
Use getClass() method to compare Objects...
I hope this code will help you...
public class Notepad {
private String name;
private int year;
public Notepad(String name, int year) {
this.name = name;
this.year = year;
}
public boolean equals(Object object) {
if (object == null || this.getClass() != object.getClass()) {
return false;
}
if (object.getClass() == this.getClass()) {
return true;
}
Notepad compared = (Notepad) object;
return object.equals(compared);
}
public static void main(String[] args) {
Notepad basics = new Notepad("Equals basics", 2000);
Notepad advanced = new Notepad("Equals advanced", 2001);
System.out.println(basics.equals(basics));
System.out.println(basics.equals(advanced));
System.out.println(basics.equals(new Notepad("Equals basics", 2000)));
System.out.println(basics.equals(new Notepad("Equals basics", 2001)));
}
}

Java equals method. How to return multiple booleans comparing each atribute inside object

import java.util.*;
public class Digimon1{
private String name;
private int hitPoints;
private double attackSpeed;
public Digimon1(String name, int hitPoints, double attackSpeed){
this.name = name;
this.hitPoints = hitPoints;
this.attackSpeed = attackSpeed;
}
public String getName(){
return this.name;
}
public double getAttackSpeed(){
return this.attackSpeed;
}
public boolean equals(Object a){
Digimon1 o = (Digimon1) a;
if (this.name == o.getName() && this.attackSpeed == o.getAttackSpeed()){
return true;
}else{
return false;
}
}
public static void main(String[] args){
List <Digimon1> digimon = new ArrayList<>();
Digimon1 gatamon = new Digimon1("Gatamon", 500, 12.9);
digimon.add(gatamon);
Digimon1 agumon = new Digimon1("agumon", 53, 9.8);//agumon
digimon.add(gatamon);
Digimon1 agumon1 = new Digimon1("agumon", 53, 9.8);//agumon1
digimon.add(gatamon);
System.out.print(agumon.equals(agumon1));
}
}
So my codes equals method should output a "true, false, true" when 2 digimons have the same name and attackspeeed. But what i understand is that my equals can return if my object is true or or false.
how do i return three boolean statments?
If I understand you in a correct way and you just really want to see 3 boolean as a result.
This is the easiest way to achieve that.
You can create bool array,
boolean array[];
array = new boolean[3];
// then you can set the result to the array like this,
if(this.name == o.getName())
array[0] = true;
if(this.attackSpeed == o.getAttackSpeed())
array[1] = true;
//...
return array;
and so on.
after control statements.
I think you can write whole version then you can return your array
The other answers have already pointed out that you can't and also shouldn't think of using Object.equals for that. One solution is to use a custom method returning a boolean array, but you could also look into EnumSets:
enum DigimonEquality {
NAME, HP, ATTACK;
}
public class Digimon {
private String name;
private int hitPoints;
private double attackSpeed;
public Digimon(String name, int hitPoints, double attackSpeed) {
super();
this.name = name;
this.hitPoints = hitPoints;
this.attackSpeed = attackSpeed;
}
public EnumSet<DigimonEquality> checkEquality(Digimon that) {
EnumSet<DigimonEquality> result = EnumSet.noneOf(DigimonEquality.class);
if (this.name.equals(that.name))
result.add(DigimonEquality.NAME);
// etc.
return result;
}
public static void main(String[] args) {
List<Digimon> digimon = new ArrayList<>();
Digimon gatamon = new Digimon("Gatamon", 500, 12.9);
digimon.add(gatamon);
Digimon agumon = new Digimon("agumon", 53, 9.8);// agumon
digimon.add(gatamon);
Digimon agumon1 = new Digimon("agumon", 53, 9.8);// agumon1
digimon.add(gatamon);
EnumSet<DigimonEquality> equality = agumon.checkEquality(agumon1);
System.out.println(
Arrays.stream(DigimonEquality.values()).map(equality::contains).collect(Collectors.toList()));
}
}
A custom method also can only accept Digimon s.t. you don't need to check/cast the type, as you would in the equals method.
EDIT: because OP is struggling with the equals implementation and maybe people new to Java read this, I want to add that you should ofc also override hashCode when you override equals
You can implement Object#equals(Object obj), but you can't change count of arguments or it signature. Implement own method, that verify multiple objects, it can be a right way.

Java POJO collection attributes

I have a POJO something like the one mentioned below. Here I'm referring Set collection attribute in POJO1. I understand that set does not contain duplicate. Do I need to override equals() and hashCode() methods in POJO2? Using a Set here is not really going to helpful unless we override equals and hashCode methods? Please help me to understand little bit more on this context!
public class POJO1 {
private String name;
private Set<POJO2> pj2;
public Company(){
pj2 = new HashSet<>();
}
//setter and getter methods
}
Yes the only way for Java to understand which objects are duplicates is to call equals() method. Default implementation of equals() checks that references of two objects point to the same location in memory.
But depending on exact implementation of your Set you might need to override hashCode/equals or implement Comparable interface.
Since you put objects of POJO2 into HashSet you need to verride hashCodeequalsmethods inPOJO2` class.
You do like this
import java.util.Set;
public class POJO1 {
private String name;
private Set<POJO2> pojo2;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<POJO2> getPojo2() {
return pojo2;
}
public void setPojo2(Set<POJO2> pojo2) {
this.pojo2 = pojo2;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
POJO1 pojo1 = (POJO1) o;
if (name != null ? !name.equals(pojo1.name) : pojo1.name != null) return false;
return pojo2 != null ? pojo2.equals(pojo1.pojo2) : pojo1.pojo2 == null;
}
#Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + (pojo2 != null ? pojo2.hashCode() : 0);
return result;
}
}
Learn more at https://docs.oracle.com/javase/10/docs/api/java/lang/Object.html#equals(java.lang.Object)

Java compare the elements of a class

I have a class name "Users" and have 2 elements (int)userId and (String)userName.
Let's said
Users obj1 = new Users(10, "User1");
Users obj2 = new Users(11, "User2");
So I want to compare obj1 to obj2
element by element
10 compare to 11,
"User1" compare to "User2".
From the research i do from web. It looks like impossible to do it whether convert it to 2d array to compare or whatever method. Is there any method to do this kind of things?
I actually want to do an audit trail so i have the object before changes and after changes, so whatever element that have changed will insert a new record in the audit_trail table with the before value and after value.
I'm a newbie to programming i tried my best to think a way but it just doesn't work. Is there any other way of doing this by SQL? i using ng-admin as (front-end) and API java http to do a update (back-end).
You need to implement the Comparable<Users> interface. If you want equality check too, then you have to override
boolean equals(Object)
and
int hashCode()
Read:
https://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html
and
Why do I need to override the equals and hashCode methods in Java?
From your question, We can compare two different objects.
Please implement the equals method to do your operations available in Comparable<Users>.
Let's say as a example below,
Class obj1 = new Class(1, "raja");
Class obj2 = new Class(2, "thiru");
The id and name are a public variable of the class. Then
override the function as,
public boolean equals(Object obj)
{
return (this.id == obj.id && this.name.equals(obj.name.equals));
}
Thanks.
You should override the .equals() method, making your Users class as follows:
public class Users {
private int mId;
private String mName;
public Users(int pId, String pName) {
mId = pId;
mName = pName;
}
public int getId() {
return mId;
}
#Override
public boolean equals(Object pObject) {
return (pObject instanceof Users && ((Users) pObject).getId() == mId);
}
}
I'd probably create a BeanDelta object
public class PropertyDelta {
private String propertyName;
private Object value1;
private Object value2;
// constructor & getters
}
public class BeanDelta<T> {
private Class<T> type;
private List<PropertyDelta> propertyDeltas = new ArrayList<>();
public BeanDelta(Class<T> type) {
this.type = type;
}
// getters
}
Then you could write a reflection based method
public <T> BeanDelta<T> getDelta(T o1, T, o2) {
Class<T> type = o1.getClass();
Method[] methods = type.getMethods();
BeanDelta<T> delta = new BeanDelta<>(type);
for (Method meth : methods) {
boolean isGetter = method.getParameterTypes().length == 0 && !method.getReturnType().equals(void.class) && meth.getName().startsWith("get");
if (isGetter) {
Object v1 = meth.invoke(o1);
Object v2 = meth.invoke(o2);
if (!Objects.equal(v1, v2)) {
String propertyName = meth.getName().substring(3);
delta.propertyDeltas.add(new PropertyDelta(propertyName, v1, v2));
}
}
}
return delta;
}
Check it out the solution proposed for do that.
http://www.codejava.net/java-core/collections/sorting-a-list-by-multiple-attributes-example

Access to array list many times

I have list (array list)that can contain many instances (between 500-3000 instances ).
during the program some function need to access to this list (many times)and search for specific instance or more ,to get the instance\s they need loop on the list and provide parentName and name (which is string) and are not uniqe key .
my question is since the list need to be accessed many time there is a way to define/design it better that the access to the list can be more efficient?
Please keep in mind that the functions that need to get instance/s from the list
cannot provide full key the can provide only name and parentName which can have more that one instance.
List<Obj> myList = new ArrayList<Obj>();
class obj
{
parentName
Name
type
curr
....
Use a Map<MyEntry, List<Obj>> where MyEntry is a class enclosing parent name and name as such:
public final class MyEntry
{
private final String parentName;
private final String name;
private final int hashCode;
public MyEntry(final String parentName, final String name)
{
this.parentName = parentName;
this.name = name;
hashCode = 31 * parentName.hashCode() + name.hashCode();
}
// Override .equals() and .hashCode()
#Override
public int hashCode()
{
return hashCode;
}
#Override
public boolean equals(final Object o)
{
if (this == o)
return true;
if (o == null)
return false;
if (getClass() != o.getClass())
return false;
final MyEntry other = (MyEntry) o;
return parentName.equals(other.parentName)
&& name.equals(other.name);
}
// Have a nice string representation
#Override
public String toString()
{
return "parent name: " + parentName + ", name: " + name;
}
}
You can, for instance, have a method in your Obj which returns the matching MyEntry object. Also, if you use Guava, have a look at MultiMap.
You will notice that the hash code is precomputed: this can be done since the MyEntry class is immutable. This allows for very fast usage as keys for a Map.
(edit: added .toString())

Categories

Resources