首页 > 解决方案 > 地图中的自定义排序顺序,与身份无关

问题描述

我有四条信息(a、b、c、d)组合在一起(如数据库表中的列)。

a 和 b 的组合是唯一的(就像数据库表中的主键)

class MyClass {
    private String a, b, c, d; //getters & setters omitted
}

class Key {
    private String a, b; //getters & setters & equals & hashcode omitted

    public int compareTo(Object obj) {
        Key key2 = (Key) obj;
        if (!this.a.equals(key2.a))
            return this.a.compareTo(key2.a);
        else
            return this.b.compareTo(key2.b);
    }
}

class Main {
    private Map<Key, MyClass> map = new TreeMap();

    void populateMap() {
        for each item in the source {
            map.put new Key(a, b), new MyClass(a, b, c, d);
        }
    }
}   

当我遍历此地图时,行首先按字段 a 排序,然后按 b 排序。但我想按 a -> c -> b 订购。

我可以将 c 添加到我的 Key 类中并相应地修改 compareTo 函数。但这感觉不对。键是标识符。并且不需要 c 来识别一行。

我应该如何修改此代码,以便 (a, b) 是标识符(等于和哈希码基于)。但是我的地图按 a -> c -> b 的顺序存储信息?

标签: java

解决方案


当您在 java 中对某些内容进行排序时,您需要的基本上是两件事:

  • 对象必须是可比较的
  • 用于比较对的 Co​​mparator 对象

有了这两件事,你可以做任何你想做的事情:

public class MyClass implements Comparable<MyClass> {

@Ovveride
public int compare(MyClass other) {
    if(this.a.compareTo(other.getA()) != 0)
      return this.a.compareTo(other.getA());
    if(this.c.compareTo(other.getC()) != 0)
      return this.c.compareTo(other.getC());
    return return this.b.compareTo(other.getB());
}
}

在主班

// you can sort only Collections so let's say you want to sort values
Collections.sort(mapValues, new Comparator<MyClass> () {
    @Ovveride
    public int compareTo(MyClass c1, MyClass c2) {
       return c1.compare(c2);
    }
});

正如我所说,您只能按键自然排序 Collection 和 TreeMap(如果键是 Comparable),因此请考虑将您的信息存储在 List/Set 中,或者像我之前写的那样放置然后检索您的值。如果要在 put 中排序,则需要传递每个元素 (a,b,c),但请记住,在每次 put 后​​排序不是一个好习惯。


推荐阅读