I am trying to add objects into a Treeset but the objects not all are getting added.
class Fruits
{
String name ;
int weight;
int price;
Fruits(String n, int w, int p)
{
this.name=n;
this.weight=w;
this.price =p;
}
#Override
public int hashCode() {
System.out.println("hashcode called");
int prime =31;
int result =1;
result = prime*result +(this.name.hashCode()+this.price+this.weight);
return result;
}
#Override
public boolean equals(Object obj) {
System.out.println("Equals called");
if(null!=obj)
{
Fruits f= (Fruits) obj;
if(this.name.equals(f.name) && this.price==f.price && this.weight == f.price)
{
return true;
}
}
return false;
}
}
class FruitsComparator implements Comparator<Fruits>
{
//Order by Name, then quanity and then Price
#Override
public int compare(Fruits f1, Fruits f2)
{
if(f1.name.equals(f2.name) && f1.weight == f2.weight && f1.price == f2.price)
{
System.out.println(1);
return 0;
}
else if(f1.name.equals(f2.name) && f1.weight==f2.weight && f1.price < f2.price)
{
System.out.println(2);
return -1;
}
else if (f1.name.equals(f2.name) && f1.weight==f2.weight && f1.price > f2.price)
{
System.out.println(3);
return 1;
}
else if (f1.name.equals(f2.name) && f1.weight<f2.weight && f1.price == f2.price)
{
System.out.println(4);
return -1;
}
else if (f1.name.equals(f2.name) && f1.weight>f2.weight && f1.price == f2.price)
{
System.out.println(5);
return 1;
}
else if (f1.name.compareTo(f2.name) <1 && f1.weight==f2.weight && f1.price == f2.price)
{
System.out.println(6);
return -1;
}
else if (f1.name.compareTo(f2.name) >1 && f1.weight==f2.weight && f1.price == f2.price)
{
System.out.println(7);
return 1;
}
return 0;
}
}
From public static void main of another class.
Fruits f1= new Fruits("Apple",1,3);
Fruits f2= new Fruits("Apple",10,1);
Fruits f3= new Fruits("Apple",15,2);
Set<Fruits> sf = new TreeSet<Fruits>(new FruitsComparator());
sf.add(f1);
sf.add(f2);
sf.add(f3);
System.out.println("--Fruits Example--");
for( Fruits f: sf)
{
System.out.println(f.name+"-"+f.weight+"-"+f.price);
}
The output I get is :
--Fruits Example--
Apple-1-3
But when I have fruits objs as below i get the all the objects
just keeping everything same but the third element.
Fruits f1= new Fruits("Apple",1,3);
Fruits f2= new Fruits("Apple",1,1);
Fruits f3= new Fruits("Apple",1,2);
The output get for this is
--Fruits Example--
Apple-1-1
Apple-1-2
Apple-1-3
So somehow my objects are treated as same when I keep different elements on weight and price. I couldn't figure out as why the objects are treated as same. Please help.
The primary issue is, you are always checking two fields to be equal and only one to be different.
At the final else, that happens if at least 2 fields are different, you return 0 which means they should be treated as equal, and that is the reason you have this issue.
Since the order you want is to first sort by name, then by quantity and then by price, remove the && f1.price == f2.price from the 4th condition onwards, and remove && f1.weight==f2.weight on the last two.
You can avoid this issue completely if you use Java 8 style.
Set<Fruits> sf = new TreeSet<Fruits>(Comparator.comparing(Fruits::getName)
.thenComparing(Fruits::getWeight)
.thenComparing(Fruits::getPrice)
);
I have added the working code in codiva - online java compiler ide. I have also included a slightly cleaner implementation in FruitsComparator.java file.
Tree related collections don't use equals() or hashCode(). Those come into play for Map.
Your conditions in the compare result in a 0, hence the fruit isn't inserted.
First Apple goes in as the tree is empty. The 2nd & 3rd Apple result in false in all the if conditions, thus returning the final 0. Put a System.out.println() before the final return to confirm.
If you want to sort the fruits first by name, then by weight & then finally by price, here's a more compact way doing it:
#Override
public int compare(Fruits f1, Fruits f2) {
if (f1.name.equals(f2.name)) {
if (f1.weight < f2.weight) {
return -1;
} else if (f1.weight > f2.weight) {
return 1;
} else {
if (f1.price < f2.price) {
return -1;
} else if (f1.price > f2.price) {
return 1;
} else {
return 0;
}
}
} else {
return f1.name.compareTo(f2.name);
}
}
TreeSet, when used with a Comparator, the elements' equality is decided by the compare method of the Comparator, otherwise would use the compareTo method of its element since they are required to implement the Comparable interface. The hashcode and equals methods will only be used by the Set interface itself (such as method contains uses equals method to check if the elements are presented). And hashcode is not something that a TreeSet to use while it is used by HashSet which is totally another way to implement Set interface. Thus, in your code, since the compare method you've overridden of the Comparator treats these elements equal, so they cannot be inserted for multiple times. One guideline that the Java Tutorial points out is, the compare method should comply with the equals methods, which is, the elements should be treated equal in the compare method if and only if the equals method do.
And in your equals method, you did use this.weight == f.price to compare two fruits, which I don't think is what you intended to do. This makes your equals methods not consistent with the compare method.
For your reference, see Java Object Ordering tutorial, and as well as a question I asked two days ago.
You have an error in your equals method in class Fruits:
if(this.name.equals(f.name) && this.price==f.price && this.weight == f.price)
should have been:
if(this.name.equals(f.name) && this.price==f.price && this.weight == f.weight)
(note the last part).
Related
public static final Comparator<Summary> COMPARATOR = (courseModel1, courseModel2) -> {
if (courseModel1.department.compareTo(courseModel2.department) > 0) {
return courseModel1;
}
if (courseModel1.department.compareTo(courseModel2.department) < 0) {
return courseModel2;
}
if (courseModel1.department.compareTo(courseModel2.department) == 0) {
if (courseModel1.number.compareTo(courseModel2.number) > 0) {
return courseModel1;
}
if (courseModel1.number.compareTo(courseModel2.number) < 0) {
return courseModel2;
}
if (courseModel1.number.compareTo(courseModel2.number) == 0) {
if (courseModel1.title.compareTo(courseModel2.title) > 0) {
return courseModel1;
}
if (courseModel1.title.compareTo(courseModel2.title) < 0) {
return courseModel2;
}
}
}
// (ERROR: missing a return statement here)
};
As mentioned in the documentation for the method compare
Returns a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.
So your code needs to return an integer instead of the objects.
If the first argument is less than the second, return -1,
If the first argument is greater than the second, return 1,
If the objects are equal return 0.
Currently, it's returning one of the parameters.
The cause of missing a return statement compilation error is a missing branch, your code can either use if/else to ensure all branches are covered, instead of just ifs, or add a default return value at the end.
Edit, more detailed info below:
What happens if the if pointed by the blue arrows is false? There's no code to indicate it.
First, Comparators return an int describing the relationship between two objects. They do not return the objects under comparison.
So you may want to simplify your comparator as follows. This works by first checking for equality(== 0). If not equal, return either -1 or 1 depending on the subsequent comparison (it must be one or the other). Otherwise, continue to the next test and check for equality of numbers and if equal, just return the numeric result of comparing titles, regardless. It would look like this.
Comparator<Summary> COMPARATOR =
(courseModel1, courseModel2) -> {
if (courseModel1.department.compareTo(
courseModel2.department) != 0) {
return courseModel1.department
.compareTo(courseModel2.department);
}
if (courseModel1.number
.compareTo(courseModel2.number) != 0) {
return courseModel1.number
.compareTo(courseModel2.number);
}
// in the last case, just return the overall comparison (-1,0, or 1).
return courseModel1.title
.compareTo(courseModel2.title);
};
But this could be simplified further by using the methods provided by the Comparator interface. In each case it will return the result of comparing Summary fields based which is less or greater. If they are equal, the comparator will then try the number, followed by the title.
Comparator<Summary> comp =
Comparator.comparing(Summary::getDepartment)
.thenComparing(Summary::getNumber)
.thenComparing(Summary::getTitle);
Regardless of the form of the Comparator, you would use it like this.
Summary sum1 = ...
Summary sum2 = ...
int cmp = COMPARATOR.compare(sum1,sum2);
if (cmp < 0) {
// do something with sum1.
} else if (cmp > 0) {
// do something with sum2.
} else {
// take some action as required.
}
The class being compared
class Summary {
public String department;
public String title;
public Integer number;
public String getDepartment() {
return department;
}
public String getTitle() {
return title;
}
public Integer getNumber() {
return number;
}
}
Lets say I have a class
public class Data{
public int k;
public int l;
public Data(int k, int l){
this.k = k;
this.l = l;
}
public boolean equals(Date m){
if(this.k == m.k && this.l = m.l)
return true;
return false;
}
}
And I add a few Data objects to a ArrayList:
ArrayList<Data> holder = new ArrayList<Data>;
Data one = new Data(0,0);
Data two = new Data(0,4);
Data three = new Data(0,5);
Why does indexOf not find this?:
holder.indexOf(new Data(0,4)); //returns -1
Is indexOf any better than going through the whole array list myself? Or am I missing something.
The indexOf() method does go through the entire list. Here's an excerpt from Java 7 source code:
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
It'd be better to let Java go through it than write it yourself. Just make sure that your equals method is sufficient at finding the object you want. You'll also want to override hashCode() as well.
I won't write your equals method out, but I would recommend that you at least:
Check for null
Test if the instances you're comparing are the same
You don't need to do if(boolean_expr) { return true; }; just return the boolean expression.
Make sure you're actually overriding your equals method - the signature of that requires an Object parameter, not Date.
The signature of your equals method is wrong. You are not overriding the equals in Object, but just overloading it.
To override the behavior of equals method in Object, your signature must exactly match with the one in Object. Try this:
public boolean equals(Object o) {
if(!(o instanceof Data)) return false;
Data other = (Data) o;
return (this.k == other.k && this.l == other.l);
}
In addition, as others suggested, it is a good idea to override hashCode method also for your object to work correctly in map based collections.
The answer from Makoto is right. The same i would say to. But you have some mistakes in your code above.
You wrote "public boolean equals(Date m){". I think, you meant Data instead of Date.
You wrote "if(this.k == m.k && this.l = m.l)". The second condition in if query have to be "==".
To your question:
Makoto's answer is one solution.
My solution is to use the help of eclipse to auto generate hashcode and equals methods. Like this:
public class Data {
// your class code here
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + k;
result = prime * result + l;
return result;
}
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof Data)) {
return false;
}
Data other = (Data) obj;
if (k != other.k) {
return false;
}
if (l != other.l) {
return false;
}
return true;
}
}
By convention you want to override hashcode also when you override equals
You will most probably find that the indexOf uses the hashcode method to match the object not the equals
If you use eclise to edit you code - eclipse will generate a good equals and hashcode method for you from the "source" menu.
i'm trying to remove duplicate objects from my array.
I have my custom which is made of two double : x and y.
What i want to do is to remove duplicate ( (x && y) == (x1 && y1)) and if x == x1 i want to keep the object which has the higher y.
ArrayList<MyObject> list = [x(0),y(0)], [x(0),y(0)], [x(0.5),y(0.5], [x(0.5),y(0.6)], [x(1),y(1)];
ArrayList<MyObject> results = [x(0),y(0)], [x(0.5),y(0.6)], [x(1),y(1)];
I tried to implement the equals method but i do not how to use it :
public boolean equals(Object obj) {
if (obj == null || !(obj instanceof MyObject)) {
return false;
}
return (this.x == ((MyObject)obj).x);
}
list is always ordered using Collections.sort by x.
Thanks for all.
Given MyObject like this:
class MyObject {
private final double x;
private final double y;
public MyObject(double x, double y) {
this.x = x;
this.y = y;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MyObject myObject = (MyObject) o;
if (Double.compare(myObject.x, x) != 0) return false;
if (Double.compare(myObject.y, y) != 0) return false;
return true;
}
#Override
public int hashCode() {
int result;
long temp;
temp = Double.doubleToLongBits(x);
result = (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(y);
result = 31 * result + (int) (temp ^ (temp >>> 32));
return result;
}
}
You can implement a unique method that returns a list with unique elements only:
private List<MyObject> unique(List<MyObject> list) {
List<MyObject> uniqueList = new ArrayList<>();
Set<MyObject> uniqueSet = new HashSet<>();
for (MyObject obj : list) {
if (uniqueSet.add(obj)) {
uniqueList.add(obj);
}
}
return uniqueList;
}
And a unit test for it to verify it works:
#Test
public void removeDups() {
List<MyObject> list = Arrays.asList(new MyObject(0, 0), new MyObject(0, 0), new MyObject(0.5, 0.5), new MyObject(0.5, 0.6), new MyObject(1, 1));
List<MyObject> results = Arrays.asList(new MyObject(0, 0), new MyObject(0.5, 0.5), new MyObject(0.5, 0.6), new MyObject(1, 1));
assertEquals(results, unique(list));
}
Note: it's important to implement both equals and hashCode for this to work,
because of the use of a hash map. But you should always do this anyway in your custom classes: provide appropriate equals and hashCode implementations. Btw, I didn't write those equals and hashCode methods. I let my IDE (IntelliJ) generate them automatically from the fields x and y of the class.
Make sure to override equals() method in your custom Object(MyObject).
Then add them into a Set. Now you have unique result set.
Use a Set instead of a List ...
You have to override equals() and hashCode(). The most IDE can generate that for you!
To "convert" a List to a Set you can simply use this:
ArrayList<MyObject> list = ...
Set<MyObject> mySet = new HashSet<MyObject>(list);
Then you have a set with unique elements. You can iterate over the set like this:
for (MyObject o : mySet){
o.getX();
}
The most optimal solution would be if you could use a Set. However, there are two Set implementations in Java: HashSet and TreeSet. HashSet requires that you declare equals and hashCode methods, while TreeSet requires your class to implement Comparable with a compareTo method or supply a Comparator. Neither solution will work in your case because you want to keep the higher y when x is equal. If you sort/calculate equality based on x, y you will have duplicate x, and if you sort/calculate equality based on x only you will get the first x entered, which is not what you want.
Therefore, what we need to do is:
Sort by x ascending, y descending
Convert to Set that preserves original order, but bases equality only on x
Convert back to list (if necessary)
XAscYdesc Comparator Method (Not accounting for nulls):
public int compare(MyObject left, MyObject right) {
int c = left.x - right.x;
if(c != 0) {
return c;
}
return right.y - left.y;
}
XAsc Comparator Method (Not accounting for nulls):
public int compare(MyObject left, MyObject right) {
return left.x - right.x;
}
(Using the Guava library; it's very useful for one-liners like this):
Collections.sort(list, new XAscYdesc());
Lists.newArrayList(ImmutableSortedSet.copyOf(new XAsc(), list));
You need to order your collection on both x and y with x first (think about it as x and y forming an hypothetical number with x on the left side of the decimal point, and y on the right side: when you sort number in growing order, if the integral parts are equal, you sort on the decimal part).
Now, with an equal predicate, it will be difficult to sort values (you can only tell if they are equal, not if one is before another). Instead, you need to implement the comparable interface, with the following method:
public int compare(Object obj) {
if (obj == null || !(obj instanceof MyObject)) {
// raise an Exception
}
MyObject other = (MyObject)obj;
if (x < other.x) return -1;
if (this.x > other.x) return 1;
if (this.y < other.y) return -1;
if (this.y > other.y) return 1;
return 0;
}
If your array is sorted according to this comparison, you just need to keep the last entry with the same x in your array to get what you want. This means that you remove entries unless its successor has a different x.
This method is interesting of you don't want to keep your original data, but only keep the result: it will update the existing array in place, for a complexity of O(n) in time (not counting the sorting, which should happen anyway if I understand your question correctly).
Alternatively, the whole filtering can be achieved by applying a fold on your collection, where folding here is simply keeping the highest y for a same x (as you stated it precisely in your question). Because your collection is already sorted on x, it means that it is naturally partitioned on values of x, so you can build a new collection by accumulating the correct x for each partition in another array. For each element of the array, you compare it with the last inserted entry in your new array, if the x are the same, you replace it with the object with the highest y. If the x are different, you add it to the new array.
The advantage of this approach is that you don't need to change the sorting algorithm, but on the other hand you need a new array. This algorithm should therefore work in O(n) space and time.
Finally, this algorithm may be adapted to an in place update of the original array. It is slightly more complicated, but would let you avoid the extra allocation (crucial on embedded systems).
Pseudo code:
int idx = 0;
while (idx + 1 < Objarray.size()){
MyObj oi = Objarray.get(idx), on = Objarray.get(idx+1);
if (oi.x == on.x) {
if (on.y < oi.y)
Objarray.remove(idx++);
else
Objarray.remove(idx+1);
} else
idx++;
}
Note that while working in constant space, it might be slightly less efficient than the allocating algorithm, because of the way ArrayList works internally (though it should be better than using other usual container types).
/**
*
*/
package test1;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* #author raviteja
*
*/
public class UinquecutomObjects {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Employee e1=new Employee();
e1.setName("abc");
e1.setNo(1);
Employee e2=new Employee();
e2.setName("def");
e2.setNo(2);
Employee e3=new Employee();
e3.setName("abc");
e3.setNo(1);
List<Employee> empList=new ArrayList<Employee>();
empList.add(e1);
empList.add(e2);
empList.add(e3);
System.out.println("list size is "+empList.size());
Set<Employee> set=new HashSet<Employee>(empList);
System.out.println("set size is "+set.size());
System.out.println("set elements are "+set);
}
}
class Employee{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
private int no;
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + no;
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Employee other = (Employee) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (no != other.no)
return false;
return true;
}
}
I want to add a method to a class I made that checks whether the two sequences have the same values in the same order.
Here is what I have so far:
public class Sequence {
private int[] values;
public Sequence(int size) { values = new int[size]; }
public void set(int i, int n) { values[i] = n; }
}
public boolean equals (Sequence other)
...??
The first part of the class I think is correct but I'm having a lot of trouble with the method that tests if the values are in the same order. Ideas and feedback would be much appreciated :)
If you want to say wether 2 Sequences are equals, you can override equals method and hashCode to follow contract.
Example using Eclipse tool:
public class Sequence {
private int[] values;
public Sequence(int size) { values = new int[size]; }
public void set(int i, int n) { values[i] = n; }
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + Arrays.hashCode(values);
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Sequence other = (Sequence) obj;
if (!Arrays.equals(values, other.values))
return false;
return true;
}
}
Then in a main class you can do the following thing
public static void main(String args[]){
Sequence s = new Sequence(5);
Sequence s2 = new Sequence(5);// new Sequence(4)
s.set(0, 1);
s2.set(0, 1);
System.out.println(s.equals(s2));//will print true
}
You have to take care that if you use my comment code (new Sequence(4)) this will return false and perhaps is not what you want! Then you will have to implement your own equals and not autogenerated by ide.
Arrays have a built in .equals() method: .equals(int[], int[])
Very simple, but hope this helps.
public boolean equals (Sequence other) {
// if sizez are different, automatic false
if (this.getValues().length != other.getValues().length)
return false;
else
int[] array1 = other.getValues();
int[] array2 = this.getValues();
// if any indices are not equal, return false
for (int i = 0; i < other.getValues().length; i++){
if (array1[i] != array2[i])
return false;
}
// it not returned false, return true
return true;
}
First and foremost, you will need to make your .equals() method a member of your Sequence class. Otherwise, you will only have access to one Sequence object.
If you want to check if 2 arrays have the same elements in the same order, all you need to do is compare each element in turn. Is the first element of this one the same as the first element of the other, etc. When you come across a pair of elements that are different, you will be able to return false. Otherwise, you can return true when you have checked each pair of elements.
One issue you may encounter is arrays of different size. Depending on what you're trying to do, you may want to either return false immediately without checking the elements or stop when you reach the end of the shorter array. Based off your question, you probably want the former, but that depends on what problem you are trying to solve.
Your .equals() method will be able to access the values arrays of both this and other even if they aren't public. This is because .equals() as a function of the Sequence class is allowed to access all the members of Sequence, even in Sequence objects other than this.
With this information, you should be able to write your .equals() method.
public boolean equals (Sequence other){
int[] first = this.getValues();
int[] second = other.getValues();
boolean same = true;
if(first.length != second.length){
return false;
}
for(int i = 0; i < first.length; i++){
if(first[i] != second[i]){
return false;
}
}
return same;
}
Note: you will have to make the values array public in the Sequence class or add a getter method to the Sequence class...a getter would be the better option
I have a class Odp. I want to use TreeSet to keep a sorted collection of Odp objects. However, I've been having problems.
public class OdpStorage {
private TreeSet<Odp> collection = new TreeSet<Odp>();
public addOdp(Odp o) {
return collection.add(o);
}
public int size() {
return collection.size();
}
}
collection.add(Odp o) is supposed to do nothing if it's already in the tree, right? Somehow, this unit test fails:
OdpStorage ts = new OdpStorage();
Odp ftw = new Odp("LOL");
Odp ktr = new Odp("OMG");
ts.addOdp(ftw);
ts.addOdp(ftw); //should do nothing
ts.addOdp(ftw); //should do nothing
ts.addOdp(ftw); //should do nothing
ts.addOdp(ktr);
assertEquals(2, ts.size());
The assertion fails. It expects 2, but the return value is 5. Why? Could the odp.equals() function be messed up?
Similarly, calling collection.contains(o) fails, even when the there is an object in the set X for which o.equals(X) returns true.
The .equals() function of Odp: (generated by Eclipse)
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof Odp))
return false;
Gene other = (Odp) obj;
if (sequence == null) {
if (other.sequence != null)
return false;
} else if (!sequence.equals(other.sequence))
return false;
return true;
}
compareTo:
/**
* this = g0
* if they are equal, g1 is presumed to come first
*
* #return -1 if g0 comes before g1; 1 if g0 comes after g1
*/
#Override
public int compareTo(Odp g1) {
if (sequence.length() < g1.getSeq().length()) {
return -1;
}
else if (sequence.length() > g1.getSeq().length()) {
return 1;
}
if (sequence.compareTo(g1.getSeq()) < 0) {
return -1;
}
return 1;
}
hashCode() is not overridden. Problem?
UPDATE
hashCode() is as follows:
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((sequence == null) ? 0 : sequence.hashCode());
return result;
}
But that still doesn't solve the problem.
Your compareTo implementation never returns 0. It should return 0 when the object instances are equal.
It appears that your collection.add(o) is failing to find the object in the backing TreeMap. Does your Odp implement Comparable or are you setting a default Comparable on your TreeSet whose compare method you have implemented? If so, you will need to ensure that your compareTo (for the Comparable), or your Comparator compare method will return 0 if the objects passed in are equals.
EDIT (in response to your comment to the original post):
It is recommended that you override HashCode() whenever you override equals()
EDIT2 in response to your compareTo implementation:
If g0 and g1 are equal, you should return 0. This is the root of the problem.
Mate cleanup your equals, its got too many if/elses. replace it with a nice do/while with lots of condition tests. If all the tests pass then reutrn true...Yes its got "goto" statements but its very easy to read and even easier to insert new conditions as necessary without lots of nesting. Nesting if/elses is evil. Using "elses" is evil and almost always never needed.
#Override
public boolean equals(final Object object) {
boolean equals = false;
do {
if (this == object) {
equals = true;
break;
}
if (false == super.equals(object)) {
break;
}
final DocumentView view = Unsafe.cast(object);
if (false == this.document.equals(view.document)) {
break;
}
if (this.revision != view.revision) {
break;
}
if (false == this.user.equals(view.user)) {
break;
}
if (false == this.timestamp.equals(view.timestamp)) {
break;
}
equals = true;
} while (false);
return equals;
}