适当的双向排序方式

时间:2012-01-30 13:14:27

标签: java sorting collections

我有一个简单的java pojo,看起来像这样:

class MyClass
{
  public String getGroup();
  public String getTitle();
}

现在我想做的是主要按getTitle()方法返回的值对MyClass pojo列表进行排序。使用我自己的比较器轻松实现。但是,我想要的是getGroup()返回的具有相同值的实例彼此跟随。现在我所做的就是

.. compare(MyClass c1, MyClass c2)
{
  if (c1.getGroup().compareTo(c2.getGroup()) == 0)
  {
    return c1.getTitle().compareTo(c2.getTitle());
  }
  return c1.getGroup().compareTo(c2.getGroup());
}

但是,此代码的问题在于它不再主要按标题排序,因为我首先比较组的内容而不是标题,因此以组“B”开头的组将在组开始之前进行比较“C”虽然它的标题可能首先出现..主要按标题排序但确保组合“组合”的正确方法是什么?

示例数据:

MyClass 1 (group = "A", title="5")
MyClass 2 (group = "B", title="9")
MyClass 3 (group = "B", title="1")

使用我之前的代码最终会进入

MyClass 1 (group = "A", title="5")
MyClass 3 (group = "B", title="1")
MyClass 2 (group = "B", title="9")

- >按组排序,然后按标题排序

但我想要

MyClass 3 (group = "B", title="1")
MyClass 2 (group = "B", title="9")
MyClass 1 (group = "A", title="5")

- >按标题排序,但要确保每个相等的组相互跟随,这就是为什么仍然MyClass 1标题为“5”的MyClass 2标题为“9”...

4 个答案:

答案 0 :(得分:1)

  

主要按标题排序的正确方法是什么,但确保群组也“组合”在一起?

要按标题排序,然后按组排序,只需在比较器中的任何位置切换getGroup()getTitle()

以下是另一种简化版本:

int compare(MyClass c1, MyClass c2)
{
  int cmp = c1.getTitle().compareTo(c2.getTitle());
  if (cmp == 0) {
    cmp = c1.getGroup().compareTo(c2.getGroup());
  }
  return cmp;
}

如果这不是您想要实现的目标,请澄清您的要求。

答案 1 :(得分:0)

您的问题没有意义:“组合在一起”意味着首先按排序,然后按标题排序。

没有绕过它。

我认为你真的想要你已编码的东西。

答案 2 :(得分:0)

尝试在Comparator中使用.getGroup而不是.getTitle(反之亦然)。我认为你应该做你正在做的事情。

答案 3 :(得分:0)

无法使用比较器完成。您需要运行已排序的标题,然后为每个未访问的标题排序相应的组。这里有一些示例代码,可以按照您想要的方式进行排序。

public class MyClass {
    private String  group;
    private String  title;

    public MyClass(String g, String t) {
        group=g;
        title=t;
    }

    static Comparator<MyClass>  TITLE_COMPARATOR    = 
            new Comparator<MyClass>() {
                    @Override
                    public int compare(MyClass c1, MyClass c2) {
                            return c1.title.compareTo(c2.title);
                    }
            };
    static Comparator<MyClass>  GROUP_COMPARATOR    = new Comparator<MyClass>() {
                    @Override
                    public int compare(MyClass c1, MyClass c2) {
                            return c1.group.compareTo(c2.group);
                    }
            };

    public static List<MyClass> sublist(List<MyClass> list, String group) {
            ArrayList<MyClass> ret = new ArrayList<MyClass>();
            for (MyClass mc : list)
                if (mc.group.equals(group))
                    ret.add(mc);
            return ret;
        }

public static void main(String[] argv) {
    ArrayList<MyClass> sorted = new ArrayList<MyClass>();

    ArrayList<MyClass> list = new ArrayList<MyClass>();
    list.add(new MyClass("A", "5"));
    list.add(new MyClass("B", "9"));
    list.add(new MyClass("B", "1"));
    Collections.sort(list, TITLE_COMPARATOR);
    Hashtable<String, Boolean> visited = new Hashtable<String, Boolean>();
    for (MyClass mc : list) {
        if (visited.get(mc.group) == null) {
            List<MyClass> sublist = sublist(list, mc.group);
            Collections.sort(sublist, GROUP_COMPARATOR);
            sorted.addAll(sublist);
            visited.put(mc.group, Boolean.TRUE);
        }
    }

    for (MyClass mc : sorted)
        System.out.println(mc.group + " " + mc.title);
}

}