【问题标题】:Comparator classes with fields带字段的比较器类
【发布时间】:2019-04-18 09:54:53
【问题描述】:

在一个使用实现Comparator接口的类的项目中,为了比较一些可比较的对象,我注意到我可以设计实现Comparator<>接口的类带有字段,然后是Override compare(...) 函数,并将类的字段用于比较函数逻辑。

所以我必须像这样调用排序函数:

Collections.sort(someArrayList, new SortClass(argument1, argument2));

我的问题是:

  • 这样的事情有多普遍?

  • 这算不算好的设计?

  • 假设我得到一个应该改变某些对象之间比较逻辑的用户输入,那么构建一个新的包装类(使用给定的参数)会被认为是一个更好的解决方案吗?

根据要求,我的 SortClass 是(我在上面的部分中对其进行了概括,但这是我真正的排序类):

public class SortHouses implements Comparator<Hotel> {

    /** if house1 should be before house2 */
    private static final int GT = -1;

    /** if house1 should be after house2 */
    private static final int LT = 1;

    private double latitude;
    private double longitude;

    public SortHouses(double latitude, double longitude){
        this.latitude = latitude;
        this.longitude = longitude;
    }

    @Override
    public int compare(House house1, House house2) {
        double distHouse1 = Math.sqrt((Math.pow((house1.getLatitude() - latitude), 2) +
                                 Math.pow((house1.getLongitude() - longitude), 2)));
        double distHouse2 = Math.sqrt((Math.pow((house2.getLatitude() - latitude), 2) +
                Math.pow((house2.getLongitude() - longitude), 2)));

        if (distHouse1 < distHouse2){
            return GT;
        }
        if (distHose1 > distHouse2) {
            return LT;
        }
        if (house1.getNum() > house2.getNum()){
           return GT;
        }
        return LT;
    }
}

【问题讨论】:

  • 你能显示你的SortClass吗?这样做没有具体问题,但您可以改用Comparator.comparing(/* based on arg1 */).thenComparing(/* based on arg2 */) 构建比较器。
  • 为什么不在课堂上实现comparable
  • 你也可以不使用你自己的类来做到这一点。使用Comparator.comparing(Function&lt;? super T,? extends U&gt;).thenComparing(Function&lt;? super T,? extends U&gt;)
  • @HusamBdr 因为该类可能不包含其元素的自然顺序。考虑一个类Car,它是一个EngineSorter
  • @HusamBdr Comparable 仅用于自然排序。它不仅仅是一个“更简单”的比较器。如果我有一个类 Person 并且我想按名称对它们进行排序,那么实现 Comparable 是没有意义的。人们不会自然地按姓名或任何其他标准排序。

标签: java comparator comparable


【解决方案1】:

这样的事情有多普遍?

参数化比较器?不是很常见。通常事物是根据它们自己的属性进行排序的。

它被认为是一个好的设计吗?

是的,如果您想按与参考位置的距离对位置进行排序,那么使用参数化的比较器似乎是实现此目的的好方法。

但是,我可以看到我不喜欢的一件事。您的 SortHotelsByProximity 实际上是在与 POI(兴趣点?)进行“秘密”比较,以防平局。

如果您将此逻辑移至第二个比较器:SortHotelsByPOI,它会更清晰,并在以后为您提供更多灵活性。您可以使用 thenComparing 方法将 Comparator 组合在一起来解释平局,这看起来像这样:

hotels.sort(new SortHotelsByProximity().thenComparing(new SortHotelsByPOI()))

假设我得到一个应该改变逻辑的用户输入 一些对象之间的比较,构建一个新的包装类(与 给定的参数)将被认为是一个更好的解决方案 有关系吗?

我不知道您所说的“包装类”是什么意思,但是如果您要问的话,可以根据用户输入动态构建比较器。

【讨论】:

  • 通过“包装类”我的意思是,构建一个新对象,其中包括作为第一个字段的旧对象和作为第二个字段的参数(比如“用户输入”),这将导致所有数组中具有相同第二个字段的对象,这对我来说又有点奇怪,我很困惑。
  • @MercyDude 仍然不清楚。就您的酒店示例而言,您会怎么做?
  • 好吧,让我解释一下,我被要求从给定的(用户给定的)地理点对一组酒店进行排序,而且酒店对象也无法更改,因此我必须在某些情况下进行操作(大概)深奥的方式。
  • @MercyDude 我认为我们在同一页上。所以你得到一个用户输入纬度/经度,然后根据该输入创建一个比较器?没有错。顺便说一句,我已经编辑了我的答案,以展示我可能会做出的一项改进。
  • hypotenuse 用作double distHouse1 = Math.hypot(house1.getLatitude() - latitude, house1.getLongitude() - longitude);
猜你喜欢
  • 2020-02-06
  • 1970-01-01
  • 1970-01-01
  • 2011-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-13
  • 2015-10-11
相关资源
最近更新 更多