使用组合而不是继承时,Comparator <t>的替代方法是什么?</t>

时间:2013-05-20 09:37:45

标签: java sorting inheritance collections composition

在重构Java项目以使用合成而没有继承时,我仍然存在一个问题,即对集合进行了多态排序。

继承示例:

public class AClass
{
    private List<OneClassOfManyThatRequireSortedInstances> unsortedList;

    public List<OneClassOfManyThatRequireSortedInstances> getSortedList()
    {
        List<OneClassOfManyThatRequireSortedInstances> sortedList = new ArrayList(this.unsortedList);
        Collections.sort(sortedList, SuperClassOfManyThatRequireSortedInstances.orderComparator);

        return sortedList;
    }
}

现在,重构后;类OneClassOfManyThatRequireSortedInstances不再继承自抽象SuperClassOfManyThatRequireSortedInstances,但Collections.sort()期望相互比较的实例。

重构这个的最佳方法是什么?

编辑:

为了完整;我已经添加了比较器实现并进一步澄清了问题。

public class SuperClassOfManyThatRequireSortedInstances
{
    private int order;

    public static final Comparator<SuperClassOfManyThatRequireSortedInstances> orderComparator = new Comparator<SuperClassOfManyThatRequireSortedInstances>()
    {
        public int compare(SuperClassOfManyThatRequireSortedInstances o1, SuperClassOfManyThatRequireSortedInstances o2)
        {
            if ((o1 == null) && (o2 == null))
            {
                return 0;
            }
            if (o1 == null)
            {
                return -1;
            }
            if (o2 == null)
            {
                return 1;
            }
            return (new Integer(o1.getOrder()).compareTo(new Integer(o2
                .getOrder())));
        }
    };


    public int getOrder()
    {
        return this.order;
    }


    public void setOrder(int order)
    {
        this.order = order;
    }
}

问题的关键在于,在重构到合成后,OneClassOfManyThatRequireSortedInstances不再"is a" SuperClassOfManyThatRequireSortedInstances,因此代码被破坏了。

许多类OneClassOfManyThatRequireSortedInstances不再拥有共同的父级。因此,只有Collections.sort()的单个实现,Comparator不能在这些类中使用。 像OneClassOfManyThatRequireSortedInstances这样的类现在改为拥有SuperClassOfManyThatRequireSortedInstances成员; "has a"关系。{{1}}

3 个答案:

答案 0 :(得分:4)

假设有两个类CarTrain。您可以创建一个类似

的界面
public interface SpeedProvider {
    int getSpeed();
}

然后,CarTrain都会实现SpeedProvider接口

public class Car implements SpeedProvider {
    int maxSpeed = 220;

    @Override
    public int getSpeed() {
        return maxSpeed;
    }
}

public class Train implements SpeedProvider {
    int maxSpeed = 300;

    @Override
    public int getSpeed() {
        return maxSpeed;
    }
}

最后,您可以实施一个比较两个Comparator

SpeedProvider
public class VehicleComparator implements Comparator<SpeedProvider> {
    @Override
    public int compare(SpeedProvider o1, SpeedProvider o2) {
        /* ... */
        return 0;
    }
}

答案 1 :(得分:1)

这个问题没有意义。 Comparator<T>用于构图。使用继承时的替代方法是Comparable<T>。你的问题又回到了前面。

答案 2 :(得分:0)

您可以通过接口获得合同,您可以根据特定的字段集(如使用的超类)返回某些排序方法。然后你可以有一个进行排序计算的类和另一组根据不同的字段/组合进行排序的类。

然后你可以简单地传递一个Comparator的实例,它将执行所需的排序,它将检查instanceof ...你可以选择抛出错误或日志,如果没有实现特定的接口,则静静地返回默认值。