2010-04-22 64 views
1

交易方式如下:对另一个物品进行排序

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

我想根据日期,标题...和按票数排序发布。

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

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

我应该返回一个散列表吗?一个treeset?数组 ?

这是我现在满脑子有点乱......

+0

这里也有点凌乱。澄清怎么样? – 2010-04-22 09:08:23

回答

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) 
+1

'Tally'是个好词:)。 – 2010-04-22 10:27:38

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)

+0

问题是,我不能直接排序我的出版物清单,因为我没有在这个清单中的投票。 – user284295 2010-04-22 09:30:06

+0

@ kevinb92:看看我的答案,例如你如何使用'Comparator'来根据外部标准进行排序。 – polygenelubricants 2010-04-22 10:34:46

+0

要完成,如果您想根据您要使用的标准(日期,标题,投票数量)来更改顺序,您只需为每个标准实施比较。 – Vinze 2010-04-22 11:29:41

3

Vinze是正确的 - 在这里推荐一个比较的使用在你的情况下,比较是有状态;在施工的时候,你必须为它提供关于不同项目的票数据(因为他们不是物品的一部分)

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

+0

+1作为地图的一个关键的任何东西的不变性。正如另一个问题所述,每次订单标准发生变化时,都必须调用排序函数(本例中为新投票)。 – Vinze 2010-04-22 11:26:27

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,即

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

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

+0

这让我觉得不好主意。让“发布”不知道它得到了多少“投票”。如果可能的话,它应该是不可变的。这种统计度量是一种不稳定的外部度量,不是“发布”本身固有的。 – polygenelubricants 2010-04-22 10:32:07

相关问题