0

I need to consult you again since I'm stuck with the following problem:

To provide logging abilities to all my project, I use a selfmade library for logging, which includes static methods for access from all classes and objects, and also an ability to dump the log contents to a file on exit. This worked well for years now, now I need to extend the library to provide a function to use several "log channels", which each represent individual logs. Each log channel is an instance of the class "Log" (see below), and then added to a list (as in class ListTest3, see below). But when trying to get a specific log from the list by creating a dummy object which has the same channel name, always -1 is returned, indicating that no object could be found. Why?

class Log:

public class Log {
  //...

  public String getChannel(){
    return channel;
  }

  //...

  public boolean equals(Log compare){
    // return getChannel().equals(compare.getChannel());
    return true;

    /**
     * used to contain a method to compare the channel names of the log
     * object itself and the provided object for comparison, now always
     * returns true for debugging purposes
     */
  }

  //...
}

For debugging, I created the following class ListTest3:

package test;

import java.util.List;
import java.util.LinkedList;

import logging.Log;

public class ListTest3 {
  public static void main(String[] args){
    List list = new LinkedList();
    Log logDefault = new Log();
    logDefault.setChannel("default");
    Log logAdvanced = new Log();
    logAdvanced.setChannel("advanced");
    Log logDebug = new Log();
    logDebug.setChannel("debug");

    list.add(logDefault);
    list.add(logAdvanced);
    list.add(logDebug);

    System.out.println("Index of logDefault: " + list.indexOf(logDefault));
    System.out.println("Index of logAdvanced: " + list.indexOf(logAdvanced));
    System.out.println("Index of logDebug: " + list.indexOf(logDebug));

    Log logDefaultDummy = new Log();
    logDefaultDummy.setChannel("default");
    System.out.println("Index of logDefaultDummy: " + list.indexOf(logDefaultDummy));

    Log logAdvancedDummy = new Log();
    logAdvancedDummy.setChannel("advanced");
    System.out.println("Index of logAdvancedDummy: " + list.indexOf(logAdvancedDummy));

    Log logDebugDummy = new Log();
    logDebugDummy.setChannel("debug");
    System.out.println("Index of logDebugDummy: " + list.indexOf(logDebugDummy));
  }
}

But instead of returning the indices of the three log objects when searching the list by their dummies, always -1 is returned, as the following output shows:

Index of logDefault: 0
Index of logAdvanced: 1
Index of logDebug: 2
Index of logDefaultDummy: -1
Index of logAdvancedDummy: -1
Index of logDebugDummy: -1

Any help is very appreciated, since I don't know how to fix this problem. Thanks for reading that batch of text! ;)

LukeLR
  • 941
  • 1
  • 9
  • 23
  • possible duplicate of [How to override equals method in java](http://stackoverflow.com/questions/8180430/how-to-override-equals-method-in-java) – Tom Jul 07 '15 at 10:07

2 Answers2

3

You haven't properly overridden equals() and hashCode() in Object. Note that the correct signature of the method is

public boolean equals(Object o)

and not

public boolean equals(Log o)

When your intention is to override/implement a method, you should always use the @Override annotation on the method. This allows avoiding mistakes like the one you did.

Also, you're reinventing the wheel. Why don't you use a real, battle-tested, efficient logging framework such as logback or log4j?

JB Nizet
  • 633,450
  • 80
  • 1,108
  • 1,174
  • Oh thanks, I completely missed that equals() requires an Object, not any class or a class of the same type. Don't know how this could occur to me :D Thank you very much for the quick reply! – LukeLR Jul 13 '15 at 15:27
1

You equals method in the Log class has the wrong signature. It should be

@Override
public boolean equals(Object compare){
    if (!(compare instanceof Log))
        return false;
    Log olog = (Log) compare;
    return getChannel().equals(olog.getChannel());
}

in order to override Object's equals method and be used by List's indexOf method.

Without overriding equals, you get the default implementation that checks reference equality, so your dummy instances are not equal to any instance in the List.

Eran
  • 359,724
  • 45
  • 626
  • 694
  • Thank you really much for the quick reply! I really appreciate that answers come so fast here at stackoverflow :D – LukeLR Jul 13 '15 at 15:28