2015-01-20 4 views
-1

나는 비슷한 질문을 많이했지만 매우 혼란 스럽다. 어쨌든 이것은 지나간 과제에 대한 것이 었습니다.맞춤형 비교기 사용하기

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 클래스를 가지고있다.
나는 선물의 arraylist 인 GiftList 클래스를 가지고 있습니다. 각 선물 목록은 최대 한 명의 자녀와 연관됩니다.
그런 다음 Giftlist의 arraylist 인 GiftSelector 클래스가 있습니다.
키가 자식 인 hashmap을 만드는 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; 
} 
} 

비교기가 정의되어 있지 않습니다. 현재 클래스 또는 giftSelector 클래스에서 비교자를 정의합니까? 또는 완전히 새로운 클래스를 제공합니까?

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

및 오버라이드 (override)은 compareTo 값과 마법의 다른 비트를 설정 포함 다음 몇 가지 물건 :
나는 내가이 곳과 같은 무언가를 필요가 있다고 생각합니다. 모든 조언을 크게 주시면 감사하겠습니다 :)

덧붙여, sortList() 메서드의 Collections.sort (presentList, comparator) 비트를 꺼내면 컴파일되고 제대로 실행됩니다. 단, presentMap의 각 자식에는 같은 가치. 그들은 모두 반복 된 마지막 선물의 선물을 담은 arraylist를 가지고 있습니다. 나는 아마 명백한 무엇인가 놓쳤다.

+1

루프 이전에 인스턴스화 된 presentList의 동일한 인스턴스에서 계속 작동하기 때문입니다. 지도에 새 목록을 추가하는 대신, 이전 목록을 참조하고 각 반복을 지우는 것입니다. – slnowak

+0

@ user4474022 내 대답이 도움이 되었습니까? 그렇다면 [승인] (http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work)을 체크 표시를 사용하여 고려하십시오. 이것은 도움이되는 답변이었고 응답자와 자신 모두에게 약간의 평판을 제공한다는 것을 더 넓은 커뮤니티에 나타냅니다. –

답변

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 등 : 필적과는 달리

는, 비교기가 허용 비교 선택적으로 할 수있다 동등 관계에 대한 요구 사항을 유지하면서 null 인수 인수

Present 클래스 안에 넣으면 쉽게 찾을 수 있으며, Present 클래스와 만 관련이 있으므로 중첩하는 것이 좋습니다. 소트 세트 (또는 소트 맵) 주문, equals와 일관성이없는 순서 부를 부과 할 수있는 비교기를 사용하는 경우

주의를 기울여야한다 : 나는 그러나 equalsaccording to the docs로와의 불일치를 기록합니다.

즉, 이제는 다른 자연 순서 정의가 동일하므로 다양한 상황에서 예기치 않은 문제가 발생할 수 있습니다.

같은 비용을 가진 두 가지 다른 선물 물건을 주문하는 방법에 대해서도 생각해보아야합니다. 당신이해야하는 모든 것을 비용으로 주문하고 있습니까?지금까지 당신의 "두 번째 질문에"늦게 편집가는

, 당신은 (자세한 설명은 this answer 참조) 그렇지 않으면 모든 맵 값은 동일의 ArrayList를 의미, 새로운 ArrayList를 당신이 반복자를 시작할 때마다 인스턴스화해야합니다