如何构建可以在不同键上编制索引和排序的数据?

时间:2013-06-12 04:16:08

标签: java collections

我想维护一组有两个主要属性的数据:1。我可以通过数字ID快速查找对象的存在,并且2.我想对数据进行排序,但要避免不必要的排序因为它可能很慢。对于更具体的示例,我有一组用户数据,其中每个用户都有一个唯一的ID(一个int)和一个唯一的用户名(一个String)。我将添加和删除用户,有时我想为用户生成一个人类可读的,按字母顺序排序的列表,但随着我的用户数量的增加,对数据进行排序所需的时间也会增加。

你会如何构建这个?我能想到的唯一合理的方法是创建两个独立的数据结构,并同时向BOTH结构冗余地添加/删除项目。随着我的数据增长,它将使用比单个结构更多的数据。我也可能会以这种方式引入更多错误,因为我必须提醒自己在以后再添加代码时将操作复制到两个结构中。换句话说,我可以:

TreeMap<String,Integer> nameSortedMap = new TreeMap<String,Integer>(String.CASE_INSENSITIVE_ORDER);

Map<Integer,String> idMap = new HashMap<Integer,String>();

每当我添加或删除数据时,我都会在两个地图上执行此操作。如果我通过ID检索用户名,我会调用idMap.get(id)或idMap.contains(id)(以查看用户是否存在)。另一方面,如果我需要显示一个排序列表,我会使用nameSortedMap.keySet(),我收集它应该已经按名称顺序排列,每次需要排序列表时都不需要额外的工作。

我的思维过程怎么样?有没有更好或更简单的方法来实现这一目标?谢谢!

2 个答案:

答案 0 :(得分:3)

我能想到两种方式:

  • 使用数据库并索引两列。数据库速度很快,而且可能非常小(参见:SQLite),但如果您不需要保存数据,或者这是您唯一可以使用的数据,那么它们可能有些过分。< / LI>
  • 创建一个包含上述两个地图的类,该类处理所有插入和删除。这样,您只有一个地方需要记住在两者上进行操作。这是object oriented programming的主要卖点之一。

答案 1 :(得分:0)

如果你不经常打电话给有序列表我不认为有必要保留两张地图,但如果你愿意这样做。我建议你创建一个类,以扩展HashMap并实现处理这两个映射的方法。例如:

public class UserMap extends HashMap<Integer, String> {

    TreeMap<String, Integer> nameSortedMap = new TreeMap<String, Integer>(String.CASE_INSENSITIVE_ORDER);

    @Override
    public String put(Integer key, String value) {
        String put = super.put(key, value);
        nameSortedMap.put(value, key);
        return put;
    }

    @Override
    public String remove(Object key) {
        String toRemove = get(key);
        if (toRemove != null) {
            remove(key);
            getOrderedName().remove(toRemove);
        }
        return toRemove;
    }

    public Set<String> getSortedNames() {
        return nameSortedMap.keySet();
    }

}