【问题标题】:CompareTo method in two separate methods两个单独的方法中的 CompareTo 方法
【发布时间】:2020-10-18 23:14:42
【问题描述】:

我有一个实现 Comparable 接口的类。 我想按对象的 ID 和名称对对象进行排序,但采用两种单独的方法。 比如按id排序:

 public int compareTo(Metro m1) {
       return this.id - m1.id;
    }

我也想按名称排序,这意味着我必须这样做:

public int compareTo(Metro m1) {
       return this.name.compareTo(m1.name);
}

问题是我不能用相同的名称和相同的参数编写相同的函数,我该如何解决这个问题? 当我在对象列表上调用 Collections.sort(this.list); 时,它如何确定我想按 id 或按名称对列表进行排序?

【问题讨论】:

  • 我不确定其他人如何使用可比性,但我只在我的班级有我想要维持的自然秩序时才使用它。出于排序目的,我使用 Collections.sort(list, Comparator)
  • @RandomCoder_01 所以你的意思是按 id 比较对象,如果它们的 id 相等则按名称比较对象?
  • 是的。只要在您创建比较器时 id 是可见的。

标签: java collections compare


【解决方案1】:

如果类型具有所谓的“自然顺序”,则实现Comparable 是合适的。这将是一个命令,是对“没有任何进一步的上下文,你认为这些对象将如何排序”的灌篮答案?

例如,如果我要求您订购“1、9 和 7”,而没有进一步的上下文,您肯定会说:嗯,嗯,我猜是 1、7、9?如果稍后我告诉你:其实我想让你用英文拼出这些数字,然后按其长度排序,所以,1,9,7 - 好吧,但这太出乎意料了。

在您的情况下,“by name”和“by id”听起来同样合理。

这意味着Metro 类型根本没有自然顺序,因此不应实现 Comparable

那么,你如何对它们进行排序?幸运的是,sort() 有一个重载:您可以提供一个 Comparator 对象。这就是你解决这个问题的方法:

// requires getId() to exist as a method:
Comparator<Metro> byUnid = comparingInt(Metro::getId);
this.list.sort(byUnid);

// Works because strings do have natural order
Comparator<Metro> byName = comparing(Metro::getName)

就这么简单。请注意,您的 compareTo by id 方法已损坏-对于非常大的数字它会失败。您应该努力在 Comparator 界面中使用comparingcomparingInt 和链接解决方案。

【讨论】:

    【解决方案2】:

    你可以使用java.util.Comparator:

    Comparator<MyClass> comparatorByName = Comparator.comparing(a -> a.name);
    Comparator<MyClass> comparatorById = Comparator.comparing(a -> a.id);
    List<MyClass> list = new ArrayList<>();
    // ...
    Collections.sort(list, comparatorByName);
    Collections.sort(list, comparatorById);
    

    【讨论】:

      【解决方案3】:

      只要您的 Comparable 对象没有在排序集合(TreeSet 等)中 您可以只为单个排序提供一个实例比较器。

      按 Y 坐标排序

      List<Point2D> points = new ArrayList();        
      Collections.sort(points, new Comparator<>() {
              @Override
              public int compare(Point2D o1, Point2D o2) {
                  return Double.compare(o1.getY(), o2.getY());
              }
       });
      

      按 X 坐标排序

       Collections.sort(points, new Comparator<>() {
                  @Override
                  public int compare(Point2D o1, Point2D o2) {
                      return Double.compare(o1.getX(), o2.getX());
                  }
           });
      

      【讨论】:

        【解决方案4】:
        
        import java.util.ArrayList;
        import java.util.Comparator;
        
        public class Test {
        
            public static void main(String[] args) {
                ArrayList<Metro> l = new ArrayList<>();
                l.add(new Metro(5, "aziz"));
                l.add(new Metro(1, "zied"));
                l.add(new Metro(2, "ahmed"));
                Comparator<Metro> byId = new Comparator<Metro>() {
                    @Override
                    public int compare(Metro o1, Metro o2) {
                        return o1.getId() - o2.getId();
                    }
                };
                l.sort(byId);
                System.out.println("by id :" + l);
                Comparator<Metro> byName = new Comparator<Metro>() {
                    @Override
                    public int compare(Metro o1, Metro o2) {
                        return o1.getName().compareTo(o2.getName());
                    }
                };
                l.sort(byName);
                System.out.println("by name :" + l);
            }
        
        }
        
        class Metro {
        
            private String name;
            private int id;
        
            Metro(int id, String name) {
                this.id = id;
                this.name = name;
            }
        
            public String getName() {
                return name;
            }
        
            public int getId() {
                return id;
            }
        
            @Override
            public String toString() {
                return "{" + id + "," + name + "}";
            }
        
        }
        

        输出:

        by id :[{1,zied}, {2,ahmed}, {5,aziz}]
        by name :[{2,ahmed}, {5,aziz}, {1,zied}]
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-08-29
          • 2023-03-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-12-25
          • 1970-01-01
          相关资源
          最近更新 更多