running boolean method from main - java

I'm trying to compare two integers or double parameters by using the method from main.
I don't understand what the problem is.
The parameters bitterChocolate_amount and milkChocolate_amount
are defined as integers.
Main:
boolean x = equals(bitterChocolate_amount,milkChocolate_amount)
Method:
public boolean equals (Fat other)
{
if (this == other) {
return true;
}
else {
return false;
}
}
The error message is
required: Object
found: int,int
reason: actual and formal argument lists differ in length
1 error

This public boolean equals (Fat other) is your method accept only one argument. But boolean x = equals(bitterChocolate_amount,milkChocolate_amount) in this you passing two argument.
Do like this
boolean x = equals(bitterChocolate_amount,milkChocolate_amount);
Method:
public boolean equals (int bitterChocolate, int milkChocolate)
{
if (bitterChocolate == milkChocolate)
return true;
else
return false;
}

This public boolean equals (Fat other) method accepts only one argument but you are passing 2 arguments here equals(bitterChocolate_amount,milkChocolate_amount) Also as you said to compare 2 integers then the method will be like this
public boolean equals (int other,int someother)

the problem is your actual and formal parameters doesn't match
you can edit your method like this.
boolean x = equals(bitterChocolate_amount,milkChocolate_amount)
Method:
public boolean equals (int value1,int value2)
{
if (value1 == value2)
{
return true;
}
else
{
return false;
}
}

Actually there is no need for an "equals" method. Simply use operators like:
if(int_a == int_b) { // returns true or false
//my code...
}
Take a look: http://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html

Like mentioned above, you're trying to pass two arguments (bitterChocolate_amount,milkChocolate_amount) to a method with only one available parameter (Fat other).
Not to mention the parameter type (Fat) is different to the arguments you're trying to pass in (int, int).
I can't really tell from the scope of the code you provided, but since you're calling that from a main class without any mention of an object instance you probably want to be declaring the method as static too.
This is bread and butter stuff here, I think you should be left alone to figure it out yourself as you'll learn a heck of a lot more that way. I'd recommend a good book if you're interested in long term investment; Head First books and Deitel and Deitel are pretty good.

You call method with one parameter and use two parameters.

The error message is self-explanatory
required: Object
found: int,int
The way you defined your equals method, it expects one parameter of type "Fat".
I assume you must have created the Fat class.
Now you are calling this method using two integer parameters, that's why its saying
required :object (of type "Fat")
and found: int, int
Now lets focus on your requirement
If you just want to compare two integer values, modify your equals method to the one defined below
public boolean equals (int value1,int value2)
{
if (value1 == value2)
{
return true;
}
else
{
return false;
}
}
In your equals method, you have used "this", which means you should call it on an object.
So it should be like this
Fat f = new Fat(3);
Fat g = new Fat(4);
f.equals(g)
But in this case, as you are comparing objects, (this==other) will not work as both the objects are different. == compares the object themselves and not the value they are storing. SO I am not sure what you want to achieve.
It will be better to get the right answer if you clarify your requirements.

Related

Understanding java compiler

Assuming I have this two classes, in separate files:
public class Text
{
public String _word;
public Text(String w)
{
_word = w;
}
public String getWord()
{
return _word;
}
public boolean equals (Text other)
{
return ((other!=null)&&(_word.equals(other._word)));
}
public boolean test (Text other)
{
return 1==1;
}
}
2nd class:
public class Sentence
{
public String _word;
public Sentence(String w)
{
_word = w;
}
public String getWord()
{
return _word;
}
public boolean equals (Object other)
{
return ((other!=null) && (other instanceof Sentence)
&& (_word.equals(((Sentence) other)._word)));
}
}
And the following main:
public static void main(String[]args){
Text y1 = new Text("abc");
Sentence z1 = new Sentence ("abc");
**
}
Let's say I run the following command where ** is:
System.out.println (y1.equals(z1));
Everything is ok, and it outputs "false".
But, if I run this command:
System.out.println (y1.test(z1));
The compiler screams "Sentence can not be converted to Text".
Two questions:
Why it works for equals but not for test? y1 is Text, so calling y1.equlas() calls to equlas() inside Text, and there it gets only Text as parameter.
If it DOES work, why the output is false? both "_word" set to "abc".
Thanks!
You've defined an equals(Text) method in Text. However, it doesn't override the existing equals(Object) method that it inherits from Object. Because of this, your equals(Text) method overloads the equals(Object) method in Object. Consequently, you can call y1.equals(z1). Because z1 is a Sentence, the equals(Object) method is the one called. The Sentence object matches Object but not Text. The equals method in Object compares object references to see if they're identical.
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).
They're not, so it returns false.
You've defined a test(Text) method in Text. There are no other overloads available, and Sentence doesn't match Text at all, so the compiler complains.
Incidentally, the equals(Object) method you've defined in Sentence is a proper override of equals, checking for null and the class of the argument.
According to the Object class definition, you inherit this in all classes
public boolean equals(Object obj)
In your case y1.equals(z1) is actually executed as y1.equals( (Object) z1), a valid cast since all objects inherit Object. You then have the above method called.
I think in Text.java you wanted to override Object.equals(Object other), but instead of overriding you created an other method with the same name (equals(Text other)), but with different parameter type.
That is why System.out.println (y1.equals(z1)); compiles: that equals call matches the signature equals(Object), which method Text inherits from Object.
On the other hand, System.out.println (y1.test(z1)); fails to compile, since Text has only 1 method with the name test, and its formal parameter type is Text, which doesn't match the type of the actual parameter (Sentence).

"Informing" the compiler what kind of ArrayList I am using

The following code is a method in a constructor. .For some reason Eclipse declares an error in the fourth line of the code "The left-hand side of an assignment must be a variable". the arraylist I am going to put as an argument in the method id made of booleans
boolean Referring(ArrayList results){
int so = 0;
int ca = 0;
if (results.get(0) **** the error is here **** = false){
return false;
}
return true;}
I think the error occurs because the compiler "doesn't know" what kind of arguments are in the ArrayList. Can I "inform him" in some way?
Two errors there.
You should declare the ArrayList as ArrayList<Boolean>, and use the double equals operator to perform comparison.
boolean Referring(ArrayList<Boolean> results){
int so = 0;
int ca = 0;
if (results.get(0) == false){
return false;
}
return true;
}
Also, with boolean, no comparison is needed. You can just use
if (!results.get(0))
I think the error occurs because the compiler "doesn't know" what kind
of arguments are in the ArrayList. Can I "inform him" in some way?
Use generics:
ArrayList<Boolean> results;
More info on generics here: http://docs.oracle.com/javase/tutorial/java/generics/
Your other problem stems from using a single = to compare a value. You should either use == or the .equals function depending on what you want to do. But since you're (presumably) working with booleans, you can just refer to them directly:
if (!results.get(0)){
You should use == as a comparison operator, not =.
Anyway you can put the type of an ArrayList between angular brackets: ArrayList<ObjectType>.

Java .equals() instanceof subclass? Why not call superclass equals instead of making it final?

It is stated in Object's .equals(Object) javadoc:
It is 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.
Almost everywhere in example code I see overridden .equals(Object) method which uses instanceof as one of the first tests, for example here: What issues / pitfalls must be considered when overriding equals and hashCode?
public class Person {
private String name;
private int age;
public boolean equals(Object obj) {
if (obj == null)
return false;
if (obj == this)
return true;
if (!(obj instanceof Person))
return false;
...
}
}
Now with class SpecialPerson extends Person having in equals:
if (!(obj instanceof SpecialPerson))
return false;
we con not guarantee that .equals() is symmetric.
It has been discussed for example here: any-reason-to-prefer-getclass-over-instanceof-when-generating-equals
Person a = new Person(), b = new SpecialPerson();
a.equals(b); //sometimes true, since b instanceof Person
b.equals(a); //always false
Maybe I should add in the beginning of SpecialPerson's equals direct call to super?
public boolean equals(Object obj) {
if( !obj instanceof SpecialPerson )
return super.equals(obj);
...
/* more equality tests here */
}
A lot of the examples use instanceof for two reasons: a) it folds the null check and type check into one or b) the example is for Hibernate or some other code-rewriting framework.
The "correct" (as per the JavaDoc) solution is to use this.getClass() == obj.getClass(). This works for Java because classes are singletons and the VM guarantees this. If you're paranoid, you can use this.getClass().equals(obj.getClass()) but the two are really equivalent.
This works most of the time. But sometimes, Java frameworks need to do "clever" things with the byte code. This usually means they create a subtype automatically. Since the subtype should be considered equal to the original type, equals() must be implemented in the "wrong" way but this doesn't matter since at runtime, the subtypes will all follow certain patterns. For example, they will do additional stuff before a setter is being called. This has no effect on the "equalness".
As you noticed, things start to get ugly when you have both cases: You really extend the base types and you mix that with automatic subtype generation. If you do that, you must make sure that you never use non-leaf types.
You are missing something here. I will try to highlight this:
Suppose you have Person person = new Person() and Person personSpecial = new SpecialPerson() then I am sure you would not like these two objects to be equal. So, its really working as required, the equal must return false.
Moreover, symmetry specifies that the equals() method in both the classes must obey it at the same time. If one equals return true and other return false, then I would say the flaw is in the equals overriding.
Your attempt at solving the problem is not correct. Suppose you have 2 subclasss SpecialPerson and BizarrePerson. With this implementation, BizarrePerson instances could be equal to SpecialPerson instances. You generally don't want that.
don't use instanceof. use this.getClass() == obj.getClass() instead. then you are checking for this exact class.
when working with equalsyou should always use the hashCode and override that too!
the hashCode method for Person could look like this:
#Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
and use it like this in your equals method:
if (this.hashCode() != obj.hashCode())
{
return false;
}
A type should not consider itself equal to an object of any other type--even a subtype--unless both objects derive from a common class whose contract specifies how descendants of different types should check for equality.
For example, an abstract class StringyThing could encapsulate strings, and provide methods to do things like convert to a string or extract substrings, but not impose any requirements on the backing format. One possible subtype of StringyThing, for example, might contain an array of StringyThing and encapsulate the value of the concatenation of all those strings. Two instances of StringyThing would be defined as equal if conversion to strings would yield identical results, and comparison between two otherwise-indistinguishable StringyThing instances whose types knew nothing about each other may have to fall back on that, but StringyThing-derived types could include code to optimize various cases. For example, if one StringyThing represents "M repetitions of character ch" and another represents "N repetitions of the string St", and the latter type knows about the first, it could check whether St contains nothing but M/N repetitions of the character ch. Such a check would indicate whether or not the strings are equal, without having to "expand out" either one of them.

Why do != and == not behave like the equals method in Java? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicates:
Java String.equals versus ==
whats the difference between ".equals and =="
public String getName() {
return new String("foobar");
}
if(getName() != "foobar2") {
//Never gets executed, it should, wtf!.
}
if(!getName().equals("foobar2")) {
//This works how it should.
}
So yeah my question is simple.. why doesn't != behave the same as !equals() aka (not Equals).
I don't see any logicial reason why one should fail, both are the same exact code in my mind, WTH.
Looking at java operators
http://download.oracle.com/javase/tutorial/java/nutsandbolts/operators.html
You can clearly see
equality == !=
are the equality operators, sure I usually use != only on numbers.. but my mind started wandering and why doesn't it work for String?
EDIT:
Here's something that looks more like the actual issue..
for (ClassGen cg : client.getClasses().values()) {
final ConstantPoolGen cp = cg.getConstantPool();
if(cp.lookupInteger(0x11223344) != -1) {
for (Method m : cg.getMethods()) {
System.out.println("lots of class spam");
if(m.getName() != "<init>") continue;
System.out.println("NEVER GETS HERE, 100% SURE IT HAS CONSTRUCTOR LOL");
}
}
}
Using != means that you check for the instance reference in the memory, and the same instance will give you true on that comparison.
When you do a new String("foobar"), a new "foobar" is created in the memory, and the comparison using == returns false.
Calling a intern() on that new string may change this behavior, since the String will now be grabbed or added to the String pool.
In any case, it's safer to use the 'equals()'.
public static void main(String[] args) throws Exception {
if (getName() != "foobar2") {
System.out.println("1");
}
if (!getName().equals("foobar2")) {
System.out.println("2");
}
}
public static String getName() {
return new String("foobar");
}
For me this outputs:
1
2
But those two checks are not equivalent. The first check is checking whether the object returned by getName() is the same object that was created for the string literal "foobar2", which it's not. The second check is probably the one you want, and it checks that the VALUE of the String object returned by the getName() method is equal to the VALUE of the String object created for your "foobar2" string literal.
So both checks will return true, the first one because they aren't the same object and the second one because the values aren't the same.
A string is an Object, not a primitive.
== and != compare two primitives to each other.
To compare strings you need to loop trough each character and compare them in order which is what .equals() does.
If you do any OOP in Java you need to override equals when you want to do equality checks on the Objects, and implement Comparable and .compare() if you want to be able to do things like sort them.
Here is a quick example of equals:
public class Person {
public name;
public Person(String name) {
this.name = name;
}
public boolean equals(Object o){
if(o instanceof Person)
if(this.name.equals(o.name))
return true;
return false;
}
}
Now a Person can be compared to another Person like:
person1.equals(person2)
Which will only return true if both people have the same name. You can define what makes two objects equal however you want, but objects are only == if they are really just two pointers to the same object in memory.
Operators only apply to primitives, not Objects, so a String comparison must be done equals, as that operates at the Object level.
--EDIT--
My comment was meant more along the lines of "the value of an Object cannot be compared in the expected way as in other languages". Of course you can use == signs, but not for a textual comparison. This is the classic question that is asked every time someone migrates to Java from a scripting language, or another language that does support operators for text comparison on Strings.

java why should equals method input parameter be Object

I'm going through a book on data structures. Currently I'm on graphs, and the below code is for the vertex part of the graph.
class Vertex<E>{
//bunch of methods
public boolean equals(Object o){
//some code
}
}
When I try to implement this equals method my compiler complains about not checking the type of the parameter and just allowing any object to be sent it. It also does seem a bit strange to me why that parameter shouldn't be a Vertex instead of an Object. Is there a reason why the author does this or is this some mistake or antiquated example?
#Override
public boolean equals(Object obj)
{
if (!(obj instanceof Vertex)) return false;
else return // blah blah
}
equals(Object) is the method defined in the root - Object. If you don't match the signature exactly, Object's version will be called when someone checks if two objects are equal. Not what you want.
You've probably seen other methods (like Comparator) where you can use the exact time. That's because those APIs were generic-ified with Java 5. Equals can't be because it is valid to call equals with two separate types. It should return false, but it is valid.
equals is a method inherited from Object, is defined to be flexible enough so that you can take any object and test if it is equal to any other object (as it rightfully should be able to do), so how could it be any other way?
Edit 1
Comment from jhlu87:
so is it not good form to write an equals method that has an input parameter of vertex?
You are welcome to create your own overload to any method, including equals, but doing so without changing the name could risk confusing many who would assume that your equals is the one that inherits from Object. If it were my code and I wanted a more specific equals method, I'd name it slightly different from just "equals" just to avoid confusion.
If your method doesn't take an argument of type Object, it isn't overriding the default version of equals but rather overloading it. When this happens, both versions exist and Java decides which one to use based on the variable type (not the actual object type) of the argument. Thus, this program:
public class Thing {
private int x;
public Thing(int x) {
this.x = x;
}
public boolean equals(Thing that) {
return this.x == that.x;
}
public static void main(String[] args) {
Thing a = new Thing(1);
Thing b = new Thing(1);
Object c = new Thing(1);
System.out.println(a.equals(b));
System.out.println(a.equals(c));
}
}
confusingly prints true for the first comparison (because b is of type Thing) and false for the second (because c is of type Object, even though it happens to contain a Thing).
It's because this method existed before generics, so for backward compatabitity it has to stay this way.
The standard workaround to impose type is:
return obj instanceof MyClass && <some condition>;
It is because the author is overriding equals. Equals is specified in java.lang.Object and is something that all classes inherrits from.
See the javadoc for java.lang.Object

Categories