I am getting an unexpected output for this. Please have a look. I am not able to find the problem. What's wrong with my program? Can anybody explain? I am getting the output
Joe Sue Mike Clare Juliet
Joe Mike Clare Juliet
objects in TreeSets and TreeMaps and with Collections.sort() for Lists, using the Comparable Interface.
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
class Person implements Comparable<Person> {
private String name;
public Person(String name) {
this.name = name;
}
public String toString() {
return name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final Person other = (Person) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public int compareTo(Person person) {
int len1 = name.length();
int len2 = person.name.length();
if(len1 > len2) {
return 1;
}
else if(len1 < len2) {
return -1;
}
else {
return 0;
}
}
}
public class App {
public static void main(String[] args) {
List<Person> list = new ArrayList<Person>();
SortedSet<Person> set = new TreeSet<Person>();
//adding Element
addElements(list);
addElements(set);
//sorting element
Collections.sort(list);
//displaying result
showElements(list);
System.out.println();
showElements(set);
}
//adding element methods
private static void addElements(Collection<Person> col) {
col.add(new Person("Joe"));
col.add(new Person("Sue"));
col.add(new Person("Juliet"));
col.add(new Person("Clare"));
col.add(new Person("Mike"));
}
private static void showElements(Collection<Person> col) {
for(Person element: col) {
System.out.println(element);
}
}
}
You are comparing the persons by the length of their names. And the names "Joe" and "Sue" have the same length. So only one of them can occur in the TreeSet. However, this comparison criterion is not consistent with the implementation of equals!
You should place your Person objects into a list, and sort this list with Collections#sort - preferably, with an own Comparator. Also see https://stackoverflow.com/a/21659849
EDIT: Further explaination:
A Set can contain each element only once. And by the way that you specified your compareTo method, you impled that "Sue" and "Joe" are equal (because their names have equal lengths). So they can not both appear in a Set.
Note: They are not really equal, based on the equals method. But the TreeSet uses the compareTo method, and this compareTo method is currently not consistent with equals. So the Set shows a wrong behavior because of your wrong compareTo method.
EDIT: A possible solution:
If the names have equal lengths, you can compare them alphabetically. This way, the compareTo method becomes consistent with equals: It will return 0 if and only if the names are equal.
@Override
public int compareTo(Person person) {
int len1 = name.length();
int len2 = person.name.length();
if(len1 > len2) {
return 1;
}
else if(len1 < len2) {
return -1;
}
else {
return name.compareTo(person.name);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With