I have a list in that list I created an object. By using the contains() method, I want to check whether the object already exists or not. For that, I override the equals() method. Everything is perfect upto this. But when I try to do the same thing for String and int the equals() override doesn't not work. Why is it like this? I just posted some sample code for reference.
public class Test
{
private int x;
public Test(int n)
{
x = n;
}
public boolean equals(Object o)
{
return false;
}
public static void main(String[] args)
{
List<Test> list = new ArrayList<Test>();
list.add(new Test(3));
System.out.println("Test Contains Object : " + list.contains(new Test(3))); // Prints always false (Equals override)
List<String> list1 = new ArrayList<String>();
list1.add("Testing");
String a = "Testing";
System.out.println("List1 Contains String : " + list1.contains(a)); // Prints true (Equals override not working)
}
}
String and Integer are both final classes, so you cannot subclass them. Therefore you cannot override their equals methods.
You can, however, subclass ArrayList and create your own contains implementation builds on the existing one.
There is no need for overriding the equals method of Integer or String as they are already implemented and work well.
However, if you want to do it anyways, this would be one way of doing it (Delegation Pattern):
public class MyString {
private String myString;
#Override
public boolean equals(Object o)
return false;
}
// add getter and setter for myString
// or delegate needed methods to myString object.
}
Of course, then you must be using this class, not the String class in your lists.
Regarding Tim's answer you can do something like this:
import java.util.*;
import java.lang.*;
import java.io.*;
class Ideone{
public static void main (String[] args) throws java.lang.Exception
{
MyString my = new MyString();
String testString = "bb";
my.setMyString(testString);
System.out.println(my.equals(testString));
}
}
class MyString {
private String myString;
#Override
public boolean equals(Object o){
return o.equals(myString);
}
public String getMyString(){
return myString;
}
public void setMyString(String newString){
myString = newString;
}
}
The output is true.
Related
I know that we can retrieve a variable's value by simply writing get methods and return var;. However, is there another way to write a get method to return information on the fields instead? If so, how does one access it. For example, if I have a planeNumber and I want to check it against another object's planeNumber, is there a way to use a boolean to check instead of writing public int getPlaneNumber()?
Seems like you are wanting to implement the Comparable interface? https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html
That is it looks like you have an attribute, planeNumber, that you want to use to compare the classes?
Maybe you want something like this
import java.util.Comparator;
import java.util.Objects;
public class Airplane implements Comparable<Airplane> {
private final int planeNumber;
public Airplane(final int planeNumber) {
this.planeNumber = planeNumber;
}
public final int getPlaneNumber() {
return planeNumber;
}
#Override
public int compareTo(final Airplane o) {
return Objects.compare(this, o, Comparator.comparing(Airplane::getPlaneNumber));
}
public static void main(final String... args) {
System.out.println(new Airplane(1).compareTo(new Airplane(2)));
System.out.println(new Airplane(100).compareTo(new Airplane(100)));
System.out.println(new Airplane(1000).compareTo(new Airplane(100)));
}
}
-1
0
1
You could add a method comparing the field values to your class like this (omitting null check in the methods):
class Scratch {
public static void main(String[] args) {
ObjectWithPlaneNumber o1 = new ObjectWithPlaneNumber(42);
ObjectWithPlaneNumber o2 = new ObjectWithPlaneNumber(42);
ObjectWithPlaneNumber o3 = new ObjectWithPlaneNumber(11);
System.out.println(o1.hasSamePlaneNumber(o2));
System.out.println(o1.hasSamePlaneNumber(o3));
}
static class ObjectWithPlaneNumber {
private final int planeNumber;
public ObjectWithPlaneNumber(int planeNumber) {
this.planeNumber = planeNumber;
}
public boolean hasSamePlaneNumber(ObjectWithPlaneNumber other) {
return this.planeNumber == other.planeNumber;
}
}
}
Trying to implement mathematical equation generation through recursively concatenating string returned by class containing same class as child nodes. Final equation contains repeated variables and I want to figure out how to end the recursion in this scenario.
I have a class1 which contains a Set/List of the same class1 objects. Also class1 contains Set/list of class2 and class3 objects. Now traversing through the parent class, I need to generate an expression from all the child and parent objects in a hierarchical manner. For eg: Exp1(class1) contains Exp2(class1), an operator(class3) and an attribute (class2). Now have to generate a long expression through the tree of objects such as class1,class2 are on the left and right sides of the equation and operator(op) in the middle.
public Map<String,String> generatecode(Map<String,String> Codes) {
String code = Codes.get("code");
String exit = Codes.get("exit");
String operator = "";
String operand1 = "";
String operand2 = "";
Set<Class2> attrs = getAttributes();
Set<Class1> exps = getExpressions();
if(attrs.size()>=2)
exit="1";
Iterator<Class2> itr = attrs.iterator();
while (itr.hasNext()) {
class2 attr=itr.next();
if(attr.getProperty("operand").equals("operand1")) {
operand1= attr.getName();
}
else if(attr.getProperty("operand").equals("operand2")) {
operand2= attr.getName();
}
}
if(!exit.equals("1") & exps!=null & !exps.isEmpty()) {
Iterator<Class1> itr = exps.iterator();
while (itr.hasNext()) {
Class1 exp=itr.next();
if(exp.getProperty("operand").equals("operand1")) {
Map<String,String> result=exp.generatecode(Map.of("code",code,"exit",exit));
exit=result.get("exit");
if(!operand1.contains(result.get("code")))
operand1+= result.get("code");
}
if(exp.getProperty("operand").equals("operand2")) {
Map<String,String> result=exp.generatecode(Map.of("code",code,"exit",exit));
exit=result.get("exit");
if(!operand2.contains(result.get("code")))
operand2+= result.get("code");
}
}
}
code += operand1+operator+operand2;
if(!exit.equals("1"))
code="";
return Map.of("code",code,"exit",exit);
}
Main class contains
Class1 aw_plus_w = new Class1();
Class3 waw_plus = new Class3("+");
aw_plus_w.addClass2(aw, Map.of("operand", "operand2"));
aw_plus_w.addClass2(w, Map.of("operand", "operand1"));
aw_plus_w.addOperator(waw_plus);
Class1 c_minus_w = new Class1();
Class3 cw_minus = new Class3("-");
c_minus_w.addClass2(c, Map.of("operand", "operand2"));
c_minus_w.addClass1(aw_plus_w, Map.of("operand", "operand1"));
c_minus_w.addOperator(cw_minus);
Class1 fr_div_size = new Class1();
Class3 fr_div = new Class3("/");
fr_div_size.addClass1(c_minus_w, Map.of("operand", "operand1"));
fr_div_size.addClass2(size, Map.of("operand", "operand2"));
fr_div_size.addOperator(fr_div);
String code="";
fr_div_size.generatecode(Map.of("code",code,"exit","0");
Expected result: ((aw+w)-c)/size
but
Actual result: ((w+aw-c-c)/(size()/(size)))
I tried for three days and could not find a way out. What is going wrong here? It will be grateful if anyone could point out the mistake
The updated sample code:
import java.util.HashSet;
import java.util.Set;
public class MyClass {
abstract class Node
{
public abstract String getCode();
// public abstract boolean isAttribute();
}
public class Attribute extends Node
{
private String name;
public Attribute(String name)
{
this.name=name;
}
public String getCode()
{
return name;
}
}
public class Expression extends Node
{
private String name;
private Set<Attribute> arg1 = new HashSet<Attribute>();
private Set<Expression> arg2 = new HashSet<Expression>();
private String op;
public Expression(Set<Attribute> arg1,Set<Expression> arg2, String op)
{
this.arg1=arg1;
this.arg2=arg2;
this.op=" "+op+" ";
}
public String getCode()
{
String result="";
// The correct code need to be written here
return result;
}
public Expression(String name)
{
this.name=name;
}
}
public static void main(String args[]) {
MyClass cl=new MyClass();
cl.run();
}
public void run(){
Attribute x=new Attribute("x");
Expression xpx=new Expression(Set.of(x,x),null,"+");
Expression xpxdx=new Expression(Set.of(x),Set.of(xpx),"/");
System.out.println(xpxdx.getCode());
}
}
I have not quite found the reason that you get the behaivor you are getting. I suspect it arises in the code you are not showing. (For example nothing in your code produces the "(" and ")" characters).
There is a likely bug though, in that at the top level you set exit="1", and you then pass that all the way down.
Your use of map to pass parameters makes your code much harder to read than it needs to be.
You should also look at polymorphism to carry the load for you.
If I understand your problem correctly the following is a simple implementation;
(Nesting of classes is because the online fiddle I was using did not allow multiple files, proper implementation should have separate classes in separate files.)
public class MyClass {
abstract class Expression
{
public abstract String getCode();
public abstract boolean isLiteral();
}
public class Literal extends Expression
{
private String name;
public Literal(String name)
{
this.name=name;
}
public String getCode()
{
return name;
}
public boolean isLiteral()
{
return true;
}
}
public class Binary extends Expression
{
private Expression arg1;
private Expression arg2;
private String op;
public Binary(Expression arg1,Expression arg2, String op)
{
this.arg1=arg1;
this.arg2=arg2;
this.op=" "+op+" ";
}
public String getCode()
{
String result="";
if(!arg1.isLiteral()) result+="("+arg1.getCode()+")";
else result+=arg1.getCode();
result+=op;
if(!arg2.isLiteral()) result+="("+arg2.getCode()+")";
else result+=arg2.getCode();
return result;
}
public boolean isLiteral()
{
return false;
}
}
public static void main(String args[]) {
MyClass cl=new MyClass();
cl.run();
}
public void run(){
Literal x=new Literal("x");
Expression xpx=new Binary(x,x,"+");
Expression xpxdx=new Binary(xpx,x,"/");
System.out.println(xpxdx.getCode());
}
}
This can be further improved by having an enumeration for the allowed operators.
Also it really should use the StringBuilder class rather than direct string concatenation.
Basically i'm attempting to write a compareTo that does the comparison based on the value of compareByWord. If compareByWord is true, I want it to compare based on the word, but if it's false, I want it to compare based on count.
class WordCount implements Comparable //Error saying WordCount must implement the inherited abstract method Comparable.compareto (Object)
{
String word;
int count;
static boolean compareByWord;
public WordCount(String aWord)
{
setWord(aWord);
count = 1;
}
private void setWord(String theWord)
{
word=theWord;
}
public void increment()
{
count+=1;
}
public static void sortByWord()
{
compareByWord = true;
}
public static void sortByCount()
{
compareByWord = false;
}
public String toString()
{
String result = String.format("%s (%d)",word, count);
return result;
}
public String getWord()
{
return word;
}
public int getCount()
{
return count;
}
#Override
public int compareTo(WordCount other) { //Error saying compareTo (WordCount) of type WordCount must override or implement a supertype method.
if (compareByWord == true)
{
return word.compareTo(other.getWord());
}
if (compareByWord == false)
{
return count.compareTo(other.getCount()); //Error saying it cannot invoke compareTo int on primitive type int.
}
return 0;
}
}
My class was perfect before I tried to implement this, not sure where I'm going wrong here. Any and all help is much appreciated.
Change the declaration to
class WordCount implements Comparable<WordCount> { // generic version
The method signature in Comparable<WordCount> is compareTo(WordCount obj) while for the raw version it's compareTo(Object obj).
With the usage of #Override, the compiler makes sure that you actually override the parent method. And the problem is that compareTo(WordCount obj) does not override compareTo(Object obj).
must implement the inherited abstract method Comparable.compareto (Object)
So pass Object, not WordCount. Now you're trying to overload this function, not override.
Use Integer count not int count. Integer is an object which implements Comparable whereas int is a primitive as the error message describes. For javadocs:
public final class Integer
extends Number
implements Comparable<Integer>
Make sure you change your accessor methods to use Integer as well of course.
That will take care of your final error.
I have a program that is zoo and in the zoo there are branched subgroups of animals that are reptiles. When I do an equals method the main program compiles and it runs. I'm confused how does java know to use the equals method if I'm comparing objects and not specifically int or String?
public class Zoo {
public static void main(String[]args) {
Animal a=new Animal("Bob");
Reptile komodo= new Reptile("Snakey");
komodo.bask();
a.size=3;
komodo.size=5;
System.out.println(a);
System.out.println(komodo);
Turtle t= new Turtle("Slowy");
t.hide();
t.size=6;
t.numlegs=4;
System.out.println(t);
System.out.println(t.equals(komodo));
}
}
public class Animal {
public String name;
public boolean equals(Animal other) {
return other.size==this.size;
}
public Animal(String s) {
name=s;
}
public void setName(String n) {
this.name=n;
}
public void eat(String meal) {
System.out.println("chump chump yummy "+meal);
}
public int size;
public String toString() {
return "I am "+name+" and I'm "+size+" cm long";
}
}
public class Reptile extends Animal {
public Reptile(String n) {
super(n);
numlegs=0;
}
public Reptile(String n, int l) {
super(n);
numlegs=l;
}
public void bask() {
System.out.println("basking...");
}
public String toString() {
return super.toString()+numlegs+" legs";
}
public int numlegs;
}
public class Turtle extends Reptile {
public Turtle(String n) {
super (n,4);
shellColor="Brown";
}
public void hide() {
System.out.println("you cant see me");
}
public String toString() {
return super.toString()+" and my shell is"+ shellColor;
}
public String shellColor;
public void bask() {
super.bask();
System.out.println("turtle is basking...");
}
}
You're not overriding the Object#equals method, but overloading it. In your method declaration you use Animal type instead of Object:
public boolean equals(Animal other)
A good overriding of the method would be using the instanceof operator. Showing an example:
#Override
public boolean equals(Object other) {
if(other instanceof Animal) {
Animal otherAnimal = (Animal)other;
//comparison logic...
}
return false;
}
More info on the subject:
Best practices regarding equals: to overload or not to overload?
Overriding Object.equals VS Overloading it
For your question on how java knows how to compare objects,
you need to override the equals method
public boolean equals(Object other){
// return true or false based on your logic
}
While comparing, equals method is used.
You can have a look at this good tutorial which explains the significance of the equals method.
http://www.thejavageek.com/2013/06/26/what-is-the-significance-of-equals-method-in-java/
Also, only overriding equals is not enough if you are using objects into collections those use hashing. You will find a good tutorial at
http://www.thejavageek.com/2013/06/28/significance-of-equals-and-hashcode/
Every class inherits the Object class silently. And the Object class has a equals method. So if any class doesn't override the equals method then it will use the default implementation of Object.equals.
From the 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).
From the source code of Object.equals
public boolean equals(Object obj) {
return (this == obj);
}
So If any object doesn't have it's own implementation of equals then the equals method will simply check if the object reference is same or not.
So get a desired result from equals you need to implement by your own as alread suggested in other answer
So I have a method as outlined below:
public interface Definitions{
public boolean isEmpty();
}
public class Methods implements Definitions{
public boolean isEmpty{
//Insert code here
}
public static void main(String[] args){
return;
}
}
This method does not take parameters/arguments when it is executed, it just has to return a boolean variable defining whether or not the original object that used it is empty or not, e.g.
public class NewClass{
public static void main(String[] args){
Methods newObject = new Methods();
return newObject.isEmpty();
}
How would I define the method "isEmpty" in order to return a true or false value? My main problem is handling / retrieving the value of the object that uses it. Thanks in advance
One thing I forgot to mention in the question is, the class Methods implements an interface. I have fixed it above. Sorry for the confusion.
might be a good idea to be able to set the state of "empty":
public class Methods implements Definitions {
private boolean empty = true;
public boolean isEmpty() {
return empty;
}
public void setEmpty(boolean empty) {
this.empty = empty;
}
public void checkIsEmpty(ObjectTypeWhichCanBeEmpty obj) {
setEmpty(obj.amIEmpty());
}
Now the million dollar question is what you're trying to do? Why not store the "empty" property in the object you want to check whether it was empty or not?
You should have some class members that are actually the state of the object, for example:
public class Methods{
private boolean empty = true;
public boolean isEmpty() {
return empty;
}
//Then, you can add some method that set the empty field:
public void fillObject() {
empty = false;
}
public void emptyObject() {
empty = true;
}
}