davidfs
davidfs

Reputation: 35

How to sort two different objects in a collection?

Suppose I have two classes CLassA and CLassB. And they have one atributte in common, for example the number of elements that each class holds.

How can i create a collection from objects of ClassA and CLassB and sort by that attribute (ascending of descending order, doesn't matter)?

I made a collection of type but when I try to implement the Comparable Interface i can't acess to that method (a get that returns the nr of elements for example).

What solutions do I have?

Thanks for your help!

Upvotes: 2

Views: 4819

Answers (4)

user unknown
user unknown

Reputation: 36229

If you have access to the declaration of CLassA and ~B, then go with a common interface, if not you could write a Wrapper for both Classes:

I defined - against the description - my own classes ~A and ~B, to have something to test. Imagine they're foreign source, and you just have access to the classes.

import java.util.*;

public class SortAB
{
    class CLassA {
        int [] elements;
        public CLassA (int [] a) {elements = a;}
        public int getElementCount () {return elements.length;}
    }

    class CLassB {
        List <Integer> elements;
        public CLassB (List <Integer> l) {elements = l;}
        public int getElementCount () {return elements.size ();}
    }

    /** a common element-count-wrapper with compareTo method */     
    abstract class EcWrapper <T> implements Comparable <EcWrapper> {
        public abstract int getElementCount ();
        public int compareTo (EcWrapper o) {return getElementCount () - o.getElementCount ();}
    }
    /** concrete Wrapper for CLassA */
    class EcAWrapper extends EcWrapper <CLassA> {
        private CLassA inner;
        public EcAWrapper (CLassA t) {
            inner = t;
        }
        public int getElementCount () {return inner.getElementCount (); }
    }
    /** concrete Wrapper for CLassB */
    class EcBWrapper extends EcWrapper <CLassB> {
        private CLassB inner;
        public EcBWrapper (CLassB t) {
            inner = t;
        }
        public int getElementCount () {return inner.getElementCount (); }
    }

    // testing
    public SortAB ()
    {
        int [] ia = {3, 5, 7, 6, 9, 11, 14}; 
        List <Integer> il = new ArrayList <Integer> (); 
        for (int i: ia) 
            il.add (i); 
        il.add (15);
        il.add (16);

        CLassA a = new CLassA (ia);
        CLassB b = new CLassB (il);
        List <EcWrapper> list = new ArrayList <EcWrapper> ();
        list.add (new EcBWrapper (b));
        list.add (new EcAWrapper (a));
        show (list);
        Collections.sort (list);
        show (list);
    }

    public static void main (String args[])
    {
        new SortAB ();
    }

    public static void show (List <EcWrapper> list)
    {
        for (EcWrapper e: list) 
            System.out.println ("\t" + e.getElementCount ());
        System.out.println ("---");
    }
}

Upvotes: 0

Andres C
Andres C

Reputation: 929

Hmm.. is it possible for ClassA and ClassB to share an interface?

interface InterfaceZ
{
    int getCount();
}

class ClassA implements InterfaceZ
{
    int getCount() { return _myArray.length; }
}
class ClassB implements InterfaceZ
{
    int getCount() { return _complexCollection.size(); }
}

Then just sort the list like so:

List<InterfaceZ> myArray;

... fill up array ...

Collections.sort(myArray, new Comparator<InterfaceZ>() {
public int compare(InterfaceZ o1, InterfaceZ o2) {
    return o2.getCount() - o1.getCount();
}});

Upvotes: 3

MeBigFatGuy
MeBigFatGuy

Reputation: 28568

Really ClassA and ClassB should be related either through an inheritance hierarchy, or by a common interface if you are going to put them both in the same collection.

The simplest thing would be to have a common interface that provides an accessor method for the common attribute. And then the comparator could use that method (through the interface) for fetching the value from ClassA's instance as well as ClassB's instance.

Upvotes: 3

ggf31416
ggf31416

Reputation: 3647

You could make a custom java.util.Comparator and sort using the Collections.sort(List list, Comparator c) method.

Upvotes: 5

Related Questions