使用自定义比较器

时间:2015-01-20 13:39:50

标签: java arraylist comparator

我查了一堆类似的问题,但仍然很困惑。无论如何,这是一个已经过去的任务。

我有一个礼物班:

public class Present implements PresentInterface{

private String name;
private String type;
private double cost;

public Present() {   
}

public Present(String name, String type, double cost) {
    this.name = name;
    this.type = type;
    this.cost = cost;
} 

然后是一堆用于获取和设置值的代码 我有一个Child课程,里面有一堆关于孩子的信息 我有一个GiftList类,它是礼物的arraylist。每个礼品清单最多与一个孩子相关联 然后我有一个GiftSelector类,它是GiftLists的一个arraylist 我想在giftSelector类中创建一个方法,该方法创建一个主题为子项的哈希映射,值为按成本排序的礼物列表。
到目前为止,我有:

    public HashMap<Child, ArrayList<Present>> sortList(){

    HashMap<Child, ArrayList<Present>> presentMap = new HashMap<Child, ArrayList<Present>>();
    ArrayList<Present> presentList = new ArrayList<Present>();

    for (GiftList giftList : giftSelector){
        presentList.clear();//clears the present list with each iteration otherwise 
        //each child would be paired with a list of presents containing those 
        //of the child before.

        Child mapChild = giftList.getChild();

        for (Present present : giftList.getAllPresents()){
            presentList.add(present);//goes through each present in the giftlist and adds it to presentlist
        }

        Collections.sort(presentList, new Comparator<Present>());

        presentMap.put(mapChild, presentList);
    }
    return presentMap;
}
}

比较器未定义,因此当然不起作用。我是在Present类中还是在giftSelector类中定义比较器,还是给它一个全新的类? 我想我需要这样的东西:

public int compare(Present p1, Present p2){
    if (p1==null || p2 == null){
        return 0;
    }
    return p1.getCost().compareTo(p2.getCost());
}

然后是一些涉及覆盖和设置compareTo值和其他魔法的东西。任何建议将不胜感激:)

顺便提一下,当我取出sortList()方法的Collections.sort(presentList,comparator)位时,它会编译并运行正常,除了presentMap中的每个子节点都具有相同的值。他们都有一个arraylist包含迭代的最后礼品清单的礼物。我可能错过了一些明显的东西。

1 个答案:

答案 0 :(得分:1)

我将它定义为静态成员类:

public class Present implements PresentInterface {
    public static class CostComparator implements Comparator<Present >
    {
        public int compare(Present p1, Present p2)
        {
            // use either this line for null
            if (p1 == null || p2 == null) throw new NullPointerException();
            // or these 2 lines for null:
            if (p1 == null) return p2 == null ? 0 : -1;
            if (p2 == null) return 1;
            // and now do a reference check for speed
            if (p1 == p2) return 0;
            // and finally the value checks
            return Double.compare(p1.cost, p2.cost);
        }
    }
    private String name;
    private String type;
    private double cost;
}

null排序有两种选择(如图所示)per the docs

  

与Comparable不同,比较器可以选择允许比较空参数,同时保持等价关系的要求

将它放在Present类中只是为了便于查找,因为它只与Present类相关,所以嵌套它是有意义的。但是,我会将其与equals标记为according to the docs

  

当使用能够强加与equals不一致的排序的比较器来排序有序集(或有序映射)时,应该小心。

即。因为它现在有一个不同的“自然顺序”定义,所以在各种情况下你可能遇到无法预料的问题。

您还应该考虑如何订购具有相同成本的两个不同的Present对象 - 按成本排序您需要做什么?

延迟编辑就你的“第二个问题”而言,每次启动迭代器时都需要实例化一个新的ArrayList,否则每个map值都引用相同的arraylist(参见{{3更多解释):

for (GiftList giftList : giftSelector){
    presentList = new ArrayList<Present>; // create a new instance of a present list with each iteration otherwise ...