我查了一堆类似的问题,但仍然很困惑。无论如何,这是一个已经过去的任务。
我有一个礼物班:
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包含迭代的最后礼品清单的礼物。我可能错过了一些明显的东西。
答案 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 ...