How to sort two different objects in a collection?

2020-04-17 05:06发布

问题:

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!

回答1:

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.



回答2:

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



回答3:

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();
}});


回答4:

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 ("---");
    }
}