用另一个对象排序

时间:2010-04-22 09:05:03

标签: java sorting

这是交易:

我的应用程序中有发布对象。 我也有投票对象(forOrAgainst,作者,linkedPublication)

我想按日期,标题......以及投票数对出版物进行排序。

我无法直接对我的出版物列表进行排序,因为我没有该列表中的投票数量。 如何在不向发布对象添加方法的情况下对发布列表进行排序。

链接它们的最佳方式是什么?

我应该返回一个hashmap吗?树集?一个数组?

现在我脑子里有点乱......

4 个答案:

答案 0 :(得分:3)

解决方案是实现接口比较器(http://java.sun.com/j2se/1.5.0/docs/api/java/util/Comparator.html),然后可以使用例如Collections.sort(列表列表,比较器比较器)函数(http://java.sun.com/j2se/1.5.0/docs/api/java/util/Collections.html#sort(java.util.List,%20java.util.Comparator)

答案 1 :(得分:3)

Vinze是对的 - 这里建议使用比较器。在您的情况下,比较器 statefull ;在施工时,您必须提供有关不同物品投票的数据(因为它们不是物品的一部分)。

如果要对列表进行排序,那么Collections.sort(..)是个好主意。另一方面,如果您决定将项目放入某种SortedSet(或SortedMap),请确保投票(以及比较器使用的其他字段)保持不变。否则,数据结构将被破坏,并且将不再保留正确的项目顺序。

答案 2 :(得分:3)

以下是使用Comparator根据外部标准进行排序的示例:

import java.util.*;

class VoteComparator implements Comparator<String> {
    final Map<String, Integer> tally;
    VoteComparator(Map<String, Integer> tally) {
        this.tally = tally;
    }
    @Override public int compare(String pub1, String pub2) {
        int v1 = tally.get(pub1);
        int v2 = tally.get(pub2);
        return
           (v1 < v2) ? -1 :
           (v1 > v2) ? +1 :
           0;
    }           
};

为了简单起见,它仅使用String进行发布;您希望在应用程序中对Publication进行排序。这也使用一个简单的int来获得投票计数,但实际上必须有一个计数服务,在Publication给出Vote计数的情况下为您提供。

  

注意:英语不是我的第一语言,所以也许“理货”不是正确的词,但基本上是某种投票注册员,投票记录员,本质上是一个对象之间的映射,以及它获得了多少票

然后你可以使用TreeSet进行排序。

public class SortExample {
    public static void main(String[] args) {
        Map<String, Integer> tally = new HashMap<String, Integer>();
        tally.put("foo", 42);
        tally.put("bar", 13);
        tally.put("Fizz", 3);
        tally.put("Buzz", 5);
        tally.put("FizzBuzz", 15);

        Comparator<String> voteComparator = new VoteComparator(tally);
        SortedSet<String> sortedByVote = new TreeSet<String>(voteComparator);
        sortedByVote.addAll(tally.keySet());
        for (String pub: sortedByVote) {
            System.out.println(pub + " (" + tally.get(pub) + " votes)");
        }
    }
}

打印:

Fizz (3 votes)
Buzz (5 votes)
bar (13 votes)
FizzBuzz (15 votes)
foo (42 votes)

答案 3 :(得分:0)

我会考虑将您的类结构重新设计为:

public class Publication implements Comparable<Publication> {
    private String title;
    private Date date;
    // etc....
    private Collection<Vote> votes;

    // Possibly even:
    private int upVotes;
    private int downVotes;

    // Constructors etc.

   // Handle votes here.
   public void addVote(Vote vote) {
       votes.add(vote);
       if (vote.isUpVote()) {
           upVotes++;
       } else {
           downVotes++;
       }
   }

   // Other methods for handling whatever you need to do.


   public int compareTo(Publication other) {
       // Now in here you can implement your sorting logic and have direct access to number of votes.
       // If you decide not to implement the counters of upVotes and downVotes then you will need to iterate over your votes collection and count them each time you do a compare, so it might be worth doing it to be more efficient.  You just have to make sure that any methods you add that affect the votes collection also updates the counters.
   }

}

public class Vote {
    private boolean isUpVote;
    private String author;
    // No need for a link to the publication now.

    public boolean isUpVote() {
        return isUpVote;
    }

    // etc.
}

现在,无论您在哪里存储出版物,都可以这样做:

Collections.sort(publications);

假设您的出版物集合是一个列表,即

List<Publication> publications = new ArrayList<Publication>();

记住(正如Eyal所说)如果你改变你的出版物的状态(即改变选票或其他任何影响排序顺序的东西)那么你将不得不求助,它不会自动发生。