2017-01-25 24 views
1

私のリストがソートされていない理由はわかりません。ソートコレクションが期待どおりに機能しない

私はCollection.sortを使用していますが、仕事をしているようですが、UnitTestを起動するとエラーが出力されます。

予想:characterWithMaxVotes [voteCount:100]

実際:characterMiddle75 [voteCount:75]それを正しく行うにはどのように

//Exact same method as in the Character class (pasted for better readability on SO question) 
public static void sortCharactersByVotes(List<Character> lstCharacters) { 
    Collections.sort(lstCharacters, new Comparator<Character>() { 
     @Override 
     public int compare(Character character, Character p1) { 
      int result = (character.getVoteCount() > p1.getVoteCount()) ? 1 : 0; 
      return result; 
     } 
    }); 
} 

@Test 
public void sortCharactersByVoteCounts() { 
    Character characterWithMinVotes = Character.newBuilder().name("characterWithMinVotes").voteCount(0).build(); 
    Character characterMiddle25 = Character.newBuilder().name("characterMiddle25").voteCount(25).build(); 
    Character characterMiddle75 = Character.newBuilder().name("characterMiddle75").voteCount(75).build(); 
    Character characterWithMaxVotes = Character.newBuilder().name("characterWithMaxVotes").voteCount(100).build(); 

    List<Character> lstCharacters = new ArrayList<>(); 

    lstCharacters.add(characterMiddle75); 
    lstCharacters.add(characterWithMaxVotes); 
    lstCharacters.add(characterMiddle25); 
    lstCharacters.add(characterWithMinVotes); 

    sortCharactersByVotes(lstCharacters); 

    System.out.print(lstCharacters); 

    assertEquals(lstCharacters.get(0), characterWithMaxVotes); 
    assertEquals(lstCharacters.get(1), characterMiddle75); 
    assertEquals(lstCharacters.get(2), characterMiddle25); 
    assertEquals(lstCharacters.get(3), characterWithMinVotes); 
} 

は、あなたの助けをありがとうございました。

PS:

要求され、ここに私の文字クラスがある

などの公共のクラス文字{

private static final String TAG = "Character"; 

private int id; 
private String name = ""; 
public int voteCount; 
public boolean isVotedByUser = false; 

public int getId() { 
    return id; 
} 
public int getVoteCount() { 
    return voteCount; 
} 
public String getName() { 
    return name; 
} 

public static CharacterBuilder newBuilder(){ 
    return new CharacterBuilder(); 
} 

@Override 
public String toString() { 
    return name + "[voteCount : " + voteCount + "]"; 
} 

public static void sortCharactersByVotes(List<Character> lstCharacters) { 
    Collections.sort(lstCharacters, new Comparator<Character>() { 
     @Override 
     public int compare(Character character, Character p1) { 
      int result = (character.getVoteCount() > p1.getVoteCount()) ? 1 : 0; 
      return result; 
     } 
    }); 
} 

public static class CharacterBuilder { 

    public Character character; 

    CharacterBuilder() { 
     character = new Character(); 
    } 

    public CharacterBuilder id(int id) { 
     character.id = id; 
     return this; 
    } 

    public CharacterBuilder name(String name) { 
     character.name = name; 
     return this; 
    } 

    public CharacterBuilder voteCount(int voteCount) { 
     character.voteCount = voteCount; 
     return this; 
    } 

    public Character build() { 
     return character; 
    } 

} 

}

+0

「キャラクター」とは何ですか? – nullpointer

+1

あなたの 'compare'は-1を返しません。 – CraigR8806

+0

p> p1 => 1、p = p1 => 0、AND p -1の場合、 int result = 0; if((character.getVoteCount()> p1.getVoteCount())){ \t result = 1; } else if((character.getVoteCount() azro

答えて

3

(提案されているようInteger.compareを使用するように編集)

compareメソッドはでなければなりません。比較されたオブジェクトは等しいランクを持つ(あなたの場合は等しい投票数)、それ以外の場合はa> bの場合は正の値、b> aの場合は負の値を返す必要があります。

public int compare(Character character, Character p1) { 
     return Integer.compare(p1.getVoteCount(), character.getVoteCount()); 
    } 

(単にオペランドを入れ替え、ソート結果を逆にする)

+0

問題が解決したら、できるだけ早くこの回答を受け入れるつもりです。 – Fundhor

+1

Integer'のcompareまたはcompartToへの委譲は、整数のオーバーフローで減算が失敗するため、はるかに優れています。 –

3

あなたComparatorの実装が正しくありません:単に、あなたは(getVoteCount()intであると仮定して)記述することができ、これを解決するために

最初に最も高い値を持ちたい場合(最初に反対の最小値ではない)、character.getVoteCount() < p1.getVoteCount()の場合は正の値を返し、character.getVoteCount() > p1.getVoteCount()の場合は負の値を返すことになっていますので、Integer.compare(int x, int y)を使用してgetVoteCount()あなたComparatorは可能性があるよう(それはintを返すと仮定):特にあなたに誤った結果を得るためにリスクを取るだろう単純な引き算でgetVoteCount()の値を比較しないでください。

new Comparator<Character>() { 
    @Override 
    public int compare(Character c1, Character c2) { 
     return Integer.compare(c2.getVoteCount(), c1.getVoteCount()); 
    } 
} 

NBオーバーフローの問題が発生しがちです。

+3

+1「getVoteCount()の値を単純減算で比較しないでください。そうしないと、不正確になるリスクがあります結果としてオーバーフローの問題が発生する可能性があります。 " –

1

コンパレータを少し変更した方が良いと思います。試してみてください:

public static void sortCharactersByVotes(List<Character> lstCharacters) { 
    Collections.sort(lstCharacters, new Comparator<Character>() { 
     @Override 
     public int compare(Character character, Character p1) { 
      int result = (character.getVoteCount() - p1.getVoteCount()); 
      return result; 
     } 
    }); 
} 

もう一つは、あなたが二回

characterWithMaxVotes

はそれが役に立てば幸いを追加しているということです!比較方法の

+1

Integerの比較またはcompartToへの委譲は、整数のオーバーフローで減算が失敗するため、はるかに優れています –

0

あなたのソートは

public static void sortCharactersByVotes(List<Character> lstCharacters) { 
    lstCharacters.sort(Comparator.comparingInt(Character::getVoteCount)); 
} 

に修正されなければならない - 比較は整数CharactergetVoteCountに基づいており、これは、Java 8+でサポートされています。

関連する問題