Forum Stats

  • 3,853,777 Users
  • 2,264,267 Discussions
  • 7,905,444 Comments

Discussions

Passing function to a class

843793
843793 Member Posts: 41,732 Green Ribbon
edited Jul 15, 2002 11:50AM in Generics
Hi !

Due to the genericity, it's possible to be in the situation of the incapacity to compare 2 objects of a user define type because the comparision field may be a special attribute in the object "type". So, is it possible to pass a compare function to a class to do the comparision ?!

Example :

In a BinaryTree class, I want to store object containing these attributes : ReferenceNumber, Name, Price. The insertion criteria in the binary tree is on the ReferenceNumber attribute. In the generic BinaryTree class, I will not know that this attribute exist because it's generic... so I want to pass to the class the functions "Equal", "LessThan" and "GreaterThan" who will compare the user define type, in the generic class.

Can I do it and if so, How can I do it ?!

Thanks !!

Pascal ;

Comments

  • 843793
    843793 Member Posts: 41,732 Green Ribbon

    One way to make things sortable is to implement the Comparable<T> interface (which is shipped with the Generic Java compiler.) You simply implement a single method like:

    public int compareTo(T obj)

    Inside that compareTo method, you can look at any of the fields in your class.

    Of course, the whole problem with this architecture is that you can't easily sort differently if you want to sort on a different field. This is exactly where pointers-to-functions would be very useful. You could pass in the right function to sort the way you want. There are lots of other places where pointers to functions would be useful.
  • 843793
    843793 Member Posts: 41,732 Green Ribbon
    I just realized my explanation wasn't clear enough. You then declare your class like:

    class BinaryTree<T implements Comparable>

    This forces the compiler to make sure that the item you're storing does indeed implement the Comparable interface.
  • 843793
    843793 Member Posts: 41,732 Green Ribbon
    As others have pointed out, you probably just want to make the class implement Comparable interface. This is how the java.util.Sorted* classes work in java (and the sorting and binary search functions in java.util.Collections and java.util.Arrays).

    For other cases where first class functions are needed, I've done stuff like the following (untested code):

    interface Filter<T>
    {
    boolean test(T t);
    }

    public interface Unary<A,B>
    {
    public B apply(A obj);
    }

    import java.util.List;
    import java.util.ArrayList;

    public class ListUtils
    {
    public static <T> List<T> grep(List<T> list, Filter<T> filter)
    {
    List<T> out = new ArrayList<T>();
    int size = list.size();
    for (int i=0;i<size;i++)
    {
    T t = list.get(i);
    if (filter.test(t))
    out.add(t);
    }
    return out;
    }
    public static <T,U> List<U> map(List<T> list, Unary<T,U> fun)
    {
    List<U> out = new ArrayList<U>();
    int size = list.size();
    for (int i=0;i<size;i++)
    out.add(fun.apply(list.get(i)));
    return out;
    }
    }

    And then made anonymous inner classes implementing Unary or Filter as needed. Not pretty, but it works.
  • 800324
    800324 Member Posts: 92
    Note that implementing Comparable only makes sense when the implementing class actually has a sensible total ordering for its instances (for example, alphanumeric in the case of String or the very obvious one in the case of Integer). For other 'business' concepts, there is often no sensible natural ordering. For example, what is a sensible natural ordering for a Complex number? I can think of two possibilities immediately and neither is a clear winner.

    In all other cases, since the sort order is determined by the context (i.e. the fact that an object has been put into a particular collection), you are better off providing a means of giving the appropriate Comparator instance to the collection to provide the ordering criteria.

    In the Collections Framework this has been done for the ordered collections by providing constructors that take a Comparator as a parameter (look at TreeSet, for example). I guess this could also be handled as a generic if you wanted.

    Regards,

    Lance
This discussion has been closed.