排名对象的数据结构

时间:2012-01-20 18:28:44

标签: java data-structures

我正在寻找一种基于给定整数对对象进行排序的数据结构。像这样:

Object    Score
Object1   86
Object2   85
Object3   85 

每个对象都是唯一的,但可能会有重复的分数。试图设计一个关于Map对象如何做到这一点的方法,但无法弄明白。

结构可以在插入期间/之后或者我隐式调用排序时对对象进行排序。

那里有结构吗?或者我应该自己编码?

4 个答案:

答案 0 :(得分:3)

如果您想要唯一值,请尝试将对象放在SortedSet中;如果要查看重复项,请尝试将List放在一起,并根据自己的“分数”自定义Comparator对其进行排序”

提供您自己的比较器将允许您指定对象应按其score字段进行排序以及如何进行排序。

如果您愿意,比较器也可以重复使用并且易于换入/换出,例如对物品进行降序排序。

这可能是一个例子:

  class ScoreComparator implements Comparator <ObjectHolder> {
    @Override
    public int compare(ObjectHolder o1, ObjectHolder o2) {
      return o1.getScore().compareTo(o2.getScore());
    }
  }

  class DescendingScoreComparator implements Comparator <ObjectHolder> {
    @Override
    public int compare(ObjectHolder o1, ObjectHolder o2) {
      return o2.getScore().compareTo(o1.getScore());
    }
  }


  class ObjectHolder {
    Object obj;
    Integer score;

    public ObjectHolder(Object o, Integer score) {
      this.obj = o;
      this.score = score;
    }

    public Object getObject() {
      return obj;
    }
    public Integer getScore() {
      return score;
    }
  }


  public void showExample() {
    SortedSet<ObjectHolder> sortedSet = new TreeSet<ObjectHolder>(new ScoreComparator());
    sortedSet.add(new ObjectHolder("addedFirst", 55));
    sortedSet.add(new ObjectHolder("addedSecond", 25));
    sortedSet.add(new ObjectHolder("addedThird", 75));
    sortedSet.add(new ObjectHolder("addedFourth", 25));
    sortedSet.add(new ObjectHolder("addedFifth", 95));

    // The resulting set will only have 4 items since sets don't allow duplicates
    for (ObjectHolder holder : sortedSet) {
      System.out.println(holder.getScore());
    }

    List<ObjectHolder> list = new LinkedList<ObjectHolder>();
    list.add(new ObjectHolder("addedFirst", 55));
    list.add(new ObjectHolder("addedSecond", 25));
    list.add(new ObjectHolder("addedThird", 75));
    list.add(new ObjectHolder("addedFourth", 25));
    list.add(new ObjectHolder("addedFifth", 95));

    Collections.sort(list, new ScoreComparator());

    // The resulting set will only have 5 items since lists allow duplicates
    System.out.println();
    for (ObjectHolder holder : list) {
      System.out.println(holder.getScore());
    }

    Collections.sort(list, new DescendingScoreComparator());

    System.out.println("\nWill print 5 items, but this time in descending order");
    for (ObjectHolder holder : list) {
      System.out.println(holder.getScore());
    }
  }

这是以上代码的输出:

  

将打印4个唯一的项目,因为集合不允许重复

     

25 55 75 95

     

将打印5个项目,因为列表允许重复

     

25 25 55 75 95

     

将打印5个项目,但这次按降序排列

     

95 75 55 25 25

答案 1 :(得分:2)

如果您需要使用地图,请使用TreeMap并提供您自己的Comparator,与@Cuga建议的SortedSet使用的相同。

答案 2 :(得分:0)

您可以尝试使用Google Guava图书馆中的TreeMultimap

这会让您将数据存储为:

得分 - &gt; [对象,对象,对象]

这样可以轻松查找具有特定分数的所有对象。但有些事情是你无法做到的:

  • 查找特定对象的分数(除MultiMap外,您还可以使用常规地图)
  • 以原子方式递增和递减分数(您需要从当前分配的分数中删除该对象并将其放入新分数中。)

答案 3 :(得分:0)

您正在寻找优先级队列。 Java不是我的主要语言,但看起来JDK已经在java.util.PriorityQueue中实现了一个。您可能必须实现自己的自定义比较器对象。

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/PriorityQueue.html

为了以适当的顺序循环遍历优先级队列,只需在循环中调用poll(),直到poll()返回null。