Please explain this compare method [duplicate] - java

This question already has answers here:
Collections.sort with multiple fields
(15 answers)
Closed 6 years ago.
public int compareTo(Name other) {
int result = this.familyName.compareTo(other.familyName);
if (result == 0) {
result = this.firstName.compareTo(other.firstName);
}
return result;
}
I can't comprehend the meat of the code, how it is used to compare names.

If the family names are the same, then it compares the first name.
Essentially "grouping by" family name.

This is the compareTo method of a class implementing the Comparable (see https://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html) interface. The return value of compareTo is defined to be 0 if the objects are identical, < 0 if the argument is lexicographically greater, and > 0 if the argument is less.
The result of the comparison of the Name object you have here is delegated to the compareTo method of the familyName attribute. That means the familyName attribute of the current Name object is compared to the argument's familyName attribute. The second compareTo check is only done if the familyName attributes of both Name object instances are identical. If that's the case, the firstName is compared instead.

Related

Why the order is reverse in equals() [duplicate]

This question already has answers here:
String.equals() argument ordering
(10 answers)
Closed 3 years ago.
In part of the code for check empty string the programmer use equals() like this:
if ("".equals(name)) {
// some logic
}
Why is it executed from a string value directly? What is the difference from this;
if (name.equals("")) {
// some logic
}
Both of them have the same result, but what is the idea behind doing the first one?
The idea behind using;
"".equals(name)
is that "" can never be null, whereas name can be. equals() accepts null as a parameter, but trying to execute a method from a null variable will result in a NullPointerException.
So this is a shorthand way to evade such possible exceptions. Same goes for any such constant object.
e.g.
final Integer CONSTANT_RATE = 123456;
....
if (CONSTANT_RATE.equals(someVariable)) { .. }
rather than doing;
if (someVariable != null && someVariable.equals(CONSTANT_RATE)) { .. }

How compare Enum Value? [duplicate]

This question already has answers here:
Why Java does not allow overriding equals(Object) in an Enum?
(6 answers)
Closed 6 years ago.
I want to compare Enum's value as in example.
public enum En{
Vanila("Good"),
Marlena("Luck"),
Garnela("Good");
private String value;
private En(String s){
this.value = s;
}
}
AS Vanila and Garnela have the same value comparing them should return true. There are two ways one is == operator and second is equals() method. I tried my own logic and add this method to enum.
public boolean compareValue(En e){
return (this.value).equals(e.value);
}
and Now it's working fine.
En a = En.Vanila;
En b = En.Garnela;
En c = En.Marlena;
if(a.compareValue(b)){
System.out.println("a == b");
}
if(a.compareValue(c)){
System.out.println("a == c");
}
if(b.compareValue(c)){
System.out.println("b == c");
}
I know we can't override equals methods in enum ( Don't know why, I know that is final but not a logically reason. Can you also explain, why we can't override equals() in enum?).
Any how is there any other way to do this effectively or is it fine?
In enum each instance is meant to represent a distinguished thing. The enum value is used to describe that thing, make it human readable, etc.
Therefore there's no reason for your code to consider that Vanilla could be equal to Marlena. And it makes no sense to set the same string values for both of them.

dosent understand how sort works

I'm trying to understand how the comparable compareTo method sort the input. Below is the compareTo method implemented:
#Override
public int compareTo(Name n) {
int lastCmp = lastName.compareTo(n.lastName);
return (lastCmp != 0 ? lastCmp : firstName.compareTo(n.firstName));
}
The input array to the Collections.sort method is:
Name nameArray[] = {
new Name("John","Smith"),
new Name("Karl","Ng"),
new Name("Jeff","Smith"),
new Name("Tom","Rich")
};
List<Name> names = Arrays.asList(nameArray);
Collections.sort(names);
I don't understand what values are taken in to the compareTo method. (n.lastName and lastname) in which order?
The Collections.sort() method uses different algorithms to sort depending on the collection length and type (I think...)
The compareTo method should return negatives, 0, or positives if the object is less-than, equal or greater-than respectively.
the lastName variable refers to the Last Name in the Name class, composed of firstName:String and lastName:String.
The method first compares the lastName (object of type String) to the lastName of the passed object "n" (of type Name). If it is different than 0 (meaning not equal) return that value. If it is equal then compare the first name and return that.
So it is only comparing the two strings (firstName and lastName of the Name objects).

String comparison in java does not gives the desired results [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 9 years ago.
I tried with the following class :
public class EqualMethodTestWithNew {
public static void main(String[] args) {
String value = "xxx";
String name = new String("xxx") ;
System.out.println("hascode : value : "+value.hashCode());
System.out.println("hascode : name : "+name.hashCode());
if (value == name) {
System.out.println("equal == 1");
} else {
System.out.println("false == 1");
}
}
}
though the hasCode is same for the both variable it prints the false == 1. could some one explain the reason why?
thanks
You need to understand what exactly is happening when you execute the 2 string statements.
String value = "xxx";
The above line creates a new compile time constant string which does into the String intern pool.
String name = new String("xxx") ;
But in this case, since you're using the new operator, it creates a new String object which goes in the object heap. It does not have the same address as the one which was created in the previous statement.
The hashCode() method is based on the contents of the String which are the same, but that doesn't mean that they both refer to the same String object in the memory.
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1] // would return same value for all String objects having the same content
To compare the values, you need to use equals() method.
And if you want to compare the object references use the == operator. In your case, since both refer to difference objects, you get the output as false.
Alternatively, you can ask the compiler to check and fetch the reference of a String with the same value already existing in the String pool by using the intern() method.
String value = "xxx";
String name = new String("xxx");
name = name.intern(); // getting reference from string pool
Now you'll get the output as equal == 1 when your do if (value == name) {.
You should be using equals method instead of == opertaor.
if (value.equals(name)) {
System.out.println("equal == 1");
} else {
System.out.println("false == 1");
}
Note that:
== tests for reference equality.
.equals() tests for value equality.
Please see here for more information.
The reason why your code is not working is that == tests whether the reference to the object is the same, and that is not your case. To compare the value of the string, you need to use the .equals(String str) method.
if (value.equals(name)) {
...
}
String should be compared with equals() method, not ==. You are trying the check the equality of the memory address of both instances (actually they are not) instead of the value in the String instances. So, use
if(value.equals(name)) {
System.out.println("equal == 1");
}
Strings are compared using equal() method. == compares the two objects are equal are not.

How do I write a compareTo method which compares objects?

I am learning about arrays, and basically I have an array that collects a last name, first name, and score.
I need to write a compareTo method that will compare the last name and then the first name so the list could be sorted alphabetically starting with the last names, and then if two people have the same last name then it will sort the first name.
I'm confused, because all of the information in my book is comparing numbers, not objects and Strings.
Here is what I have coded so far. I know it's wrong but it at least explains what I think I'm doing:
public int compare(Object obj) // creating a method to compare
{
Student s = (Student) obj; // creating a student object
// I guess here I'm telling it to compare the last names?
int studentCompare = this.lastName.compareTo(s.getLastName());
if (studentCompare != 0)
return studentCompare;
else
{
if (this.getLastName() < s.getLastName())
return - 1;
if (this.getLastName() > s.getLastName())
return 1;
}
return 0;
}
I know the < and > symbols are wrong, but like I said my book only shows you how to use the compareTo.
This is the right way to compare strings:
int studentCompare = this.lastName.compareTo(s.getLastName());
This won't even compile:
if (this.getLastName() < s.getLastName())
Use
if (this.getLastName().compareTo(s.getLastName()) < 0) instead.
So to compare fist/last name order you need:
int d = getFirstName().compareTo(s.getFirstName());
if (d == 0)
d = getLastName().compareTo(s.getLastName());
return d;
The compareTo method is described as follows:
Compares this object with the specified object for order. Returns a
negative integer, zero, or a positive integer as this object is less
than, equal to, or greater than the specified object.
Let's say we would like to compare Jedis by their age:
class Jedi implements Comparable<Jedi> {
private final String name;
private final int age;
//...
}
Then if our Jedi is older than the provided one, you must return a positive, if they are the same age, you return 0, and if our Jedi is younger you return a negative.
public int compareTo(Jedi jedi){
return this.age > jedi.age ? 1 : this.age < jedi.age ? -1 : 0;
}
By implementing the compareTo method (coming from the Comparable interface) your are defining what is called a natural order. All sorting methods in JDK will use this ordering by default.
There are ocassions in which you may want to base your comparision in other objects, and not on a primitive type. For instance, copare Jedis based on their names. In this case, if the objects being compared already implement Comparable then you can do the comparison using its compareTo method.
public int compareTo(Jedi jedi){
return this.name.compareTo(jedi.getName());
}
It would be simpler in this case.
Now, if you inted to use both name and age as the comparison criteria then you have to decide your oder of comparison, what has precedence. For instance, if two Jedis are named the same, then you can use their age to decide which goes first and which goes second.
public int compareTo(Jedi jedi){
int result = this.name.compareTo(jedi.getName());
if(result == 0){
result = this.age > jedi.age ? 1 : this.age < jedi.age ? -1 : 0;
}
return result;
}
If you had an array of Jedis
Jedi[] jediAcademy = {new Jedi("Obiwan",80), new Jedi("Anakin", 30), ..}
All you have to do is to ask to the class java.util.Arrays to use its sort method.
Arrays.sort(jediAcademy);
This Arrays.sort method will use your compareTo method to sort the objects one by one.
Listen to #milkplusvellocet, I'd recommend you to implement the Comparable interface to your class as well.
Just contributing to the answers of others:
String.compareTo() will tell you how different a string is from another.
e.g. System.out.println( "Test".compareTo("Tesu") ); will print -1
and System.out.println( "Test".compareTo("Tesa") ); will print 19
and nerdy and geeky one-line solution to this task would be:
return this.lastName.equals(s.getLastName()) ? this.lastName.compareTo(s.getLastName()) : this.firstName.compareTo(s.getFirstName());
Explanation:
this.lastName.equals(s.getLastName()) checks whether lastnames are the same or not
this.lastName.compareTo(s.getLastName()) if yes, then returns comparison of last name.
this.firstName.compareTo(s.getFirstName()) if not, returns the comparison of first name.
You're almost all the way there.
Your first few lines, comparing the last name, are right on track. The compareTo() method on string will return a negative number for a string in alphabetical order before, and a positive number for one in alphabetical order after.
Now, you just need to do the same thing for your first name and score.
In other words, if Last Name 1 == Last Name 2, go on a check your first name next. If the first name is the same, check your score next. (Think about nesting your if/then blocks.)
Consider using the Comparator interface described here which uses generics so you can avoid casting Object to Student.
As Eugene Retunsky said, your first part is the correct way to compare Strings. Also if the lastNames are equal I think you meant to compare firstNames, in which case just use compareTo in the same way.
if (s.compareTo(t) > 0) will compare string s to string t and return the int value you want.
public int Compare(Object obj) // creating a method to compare {
Student s = (Student) obj; //creating a student object
// compare last names
return this.lastName.compareTo(s.getLastName());
}
Now just test for a positive negative return from the method as you would have normally.
Cheers
A String is an object in Java.
you could compare like so,
if(this.lastName.compareTo(s.getLastName() == 0)//last names are the same
I wouldn't have an Object type parameter, no point in casting it to Student if we know it will always be type Student.
As for an explanation, "result == 0" will only occur when the last names are identical, at which point we compare the first names and return that value instead.
public int Compare(Object obj)
{
Student student = (Student) obj;
int result = this.getLastName().compareTo( student.getLastName() );
if ( result == 0 )
{
result = this.getFirstName().compareTo( student.getFirstName() );
}
return result;
}
If you using compare To method of the Comparable interface in any class.
This can be used to arrange the string in Lexicographically.
public class Student() implements Comparable<Student>{
public int compareTo(Object obj){
if(this==obj){
return 0;
}
if(obj!=null){
String objName = ((Student)obj).getName();
return this.name.comapreTo.(objName);
}
}

Categories