General question: Object.equals vs. member evaluation

Discussion in 'Plugin Development' started by bergerkiller, Aug 18, 2011.

Thread Status:
Not open for further replies.
  1. Offline

    bergerkiller

    This is one of those simple things I sometimes think of while building citylines of code. What is better in the following scenario.

    You have a class:
    Code:
    public class Test {
        public int a;
        public int b;
        public int c;
        public int d;
    }
    Now I need to compare two instances of this class if they are ACTUALLY equal, in the terms of a == a, b== b, etc.
    Code:
    Test t1 = ...;
    Test t2 = ...;
    What is the best method to check if this is true?

    1.
    Code:
    if (t1.equals(t2)) {
        // code
    }
    (class does not override equals)

    2.
    Code:
    if (t1.a == t2.a && t1.b == t2.b && t1.c == t2.c && t1.d == t2.d) {
        // code
    }
    I currently use equals, since it works. But it uses the Object hashcode algoritm, so some heavy processing still occurs in the background. Usually I wouldn't mind, but I now loop through all entities in the world for every Minecart in the world during every tick. I badly need to know the best possible way to achieve this. :)
     
  2. Hm, for the sake of maintainability, I would let your class override equals(Object o).
    But if you have the part where you check equality only once, the second is probably better (as no additional method call is needed, but that really shouldn't impact on your performance (as that is like multiplying 0 with something)).

    To be honest, I got no idea. :eek:
     
  3. Offline

    MadMonkeyCo

    I had the same thought when coding in C# XNA, but in my opinion the best way to do this is to create a method in a class called equals and instead of making it take an object as a parameter I use the type of the class.
    Code:
    public class Test {
        public int a;
        public int b;
        public int c;
        public int d;
        public boolean equals(Test arg)
        {
            return (t1.a == t2.a && t1.b == t2.b && t1.c == t2.c && t1.d == t2.d); // I think this works
        }
    }
     
  4. Offline

    bergerkiller

    I have to compare two native AxisAligned classes (bounding boxes) if they match. The class contains 6 double values, and I can't override the equals method in this case. I only need to check once, but I probably add a function for it under Util anyway. So I should evaluate the values instead of using equals? I have no idea if == takes long to process...lol

    In other words; use this instead of .equals?:
    Code:
        public static boolean equals(AxisAlignedBB aa1, AxisAlignedBB aa2) {
            if (aa1.a != aa2.a) return false;
            if (aa1.b != aa2.b) return false;
            if (aa1.c != aa2.c) return false;
            if (aa1.d != aa2.d) return false;
            if (aa1.e != aa2.e) return false;
            if (aa1.f != aa2.f) return false;
            return true;
        }
     
  5. Offline

    MadMonkeyCo

    That looks good but maybe you should use a logical OR (||) and a single if check instead of 6 if checks.
     
  6. When comparing doubles, you should allow a tiny error (as doubles lose accuracy depending on the system), like
    Code:java
    1. if (aa1.a - aa2.a =< 1E-5) {do stuff}
     
  7. Offline

    bergerkiller

    Aaaand I just found out that the bounding boxes are the same instances and I could simply use ==.
    And yep Pand, you are right. I had to do the same multiple times to see if a cart was moving or not. (I used 0.001 there though)

    I'll remember to do member evaluation in the future if this is appropriate for the situation...not to compare the same instance.

    @MadMonkeyCo I hate having long || lines, I usually solve this by returning from the function. (if a == a the remaining if calls don't get called)
     
  8. Offline

    EdTheLoon

    Remember you can multi-line your if conditions for readability :)

    Example:
    Code:java
    1.  
    2. if (aa1.a != aa2.a || aa1.b != aa2.b
    3. || aa1.c != aaa2.c || aa1.d != aa2.d) {
    4. // do something
    5. }
     
  9. Offline

    bergerkiller

    @EdTheLoon for some reason by code always end up looking real bad when I do that...especially after I use formatting. Thus, to keep the length down, I come up with those solutions...lol.

    Code:java
    1. public void foo(String type, int typeid) {
    2. if ((type.equals("aaa") && typeid == 1)
    3. || (type.equals("bbb") && typeid == 2)
    4. || (type.equals("ccc") && typeid == 3)
    5. || (type.equals("ddd") && typeid == 4)
    6. || (type.equals("eee") && typeid == 5)
    7. || (type.equals("fff") && typeid == 6)
    8. || (type.equals("ggg") && typeid == 7)
    9. || (type.equals("hhh") && typeid == 8)
    10. || (type.equals("iii") && typeid == 9)) {
    11. //Yay :D
    12. }
    13. }

    I guess it has to do with the line being at the same indent as the code executed by the if-statement, it can get confusing in certain situations.

    EDIT

    Yay black java styled syntax box is successful :D
     
  10. Offline

    EdTheLoon

    I guess it's just personal preference and coding style :) And yes...we all have a coding style :D Mine is n00b :cool:
    Haha. The only problem I have is that if you copy and paste code from a thread and then into a syntax box it adds all this formatting crap so I then have to put the copied code into notepad, copy it from notepad and then paste it again in the reply box -.-

    Example (let's hope this works):
    Code:java
    1.  
    2. [FONT=Consolas]if (t1.equals(t2)) { // code }[/FONT]
    3. [FONT=Consolas][/FONT]


    Edit: Success!
     
  11. Offline

    bergerkiller

    Ah yes. Well I have had a worse experience with it:
    - User places code in a syntax box in a spoiler, I try to 'repair' this
    - Copy code, paste in field. Wrong font, indent gone.
    - Paste in notepad - formatting gone
    - Paste in Word - success!
    - Copy and paste back in reply field
    - Forget to change font back
    - NOooooooooooooooooooooooooooo.....
    - Forget about it. xD
     
  12. Offline

    EdTheLoon

    I've had very similar experiences. It's not pleasant :) I think this is all down to how your browser copies code (if it copies the formatting or not) and I'm sure they all copy the formatting now a days :/
     
  13. @bergerkiller: If you got code like above you might want to consider using enums. :p
     
  14. Offline

    xZise

    Depends on your hashcode algoritm? I don't see any one in your code, and thus it will simply return the reference (aka pointer) so equals is by default the same as comparing the references directly:
    Code:Java
    1. Object a = ...
    2. Object b = ...
    3.  
    4. System.out.println(a == b);
    5. System.out.println(a.equals(b));

    Both are equals, as long as the hashcode/equals method wasn't changed.

    Fabian
     
  15. Offline

    bergerkiller

    @xZise this means that you should use == when equals is not being overridden by the class? Object.equals is simply a place holder for classes to build on?
     
  16. Offline

    xZise

    Yep. So you could always use equals. And if the class then implements it, nobody has to change anything. But, then you need your own hashcode as both are working together:
    If equals is true, the hashcode of both objects must be equals.

    Fabian
     
  17. Offline

    feildmaster

    Switch to the BBC Editor when pasting into the forums.
     
Thread Status:
Not open for further replies.

Share This Page