Reputation: 831
Collections.sort seems to not sort my ArrayLists even though the Comparator seems to be called properly. It appears that after performing the sort on each Arraylist the sort does not stick, the items in ArrayLists remain in their original order.
This is how I go through each Arraylist and sort them, then I print them to check:
public void SortCreatures ( int x ) {
for ( Party p : SorcerersCave.theCave.parties ) {
//cycles through parties to sort each ones ArrayList members
switch ( x ) {
case 0 :
Collections.sort( p.members, new compareThings.CEmpathy());
case 1 :
Collections.sort( p.members, new compareThings.CFear() );
case 2 :
Collections.sort( p.members, new compareThings.CCarry() );
}
}
generateInterface.theGame.printOutput( "Displaying Sorted Creatures:" );
for ( Party p : SorcerersCave.theCave.parties ) {
generateInterface.theGame.printOutput( "" + p );
for ( Creature c : p.members ){
generateInterface.theGame.printOutput( "\t" + c );
}
}
}
This is the output when using case 0: (the 5th Int in the 5th column is Empathy):
Displaying Sorted Creatures:
10000 - School//Party for refference
20002 - Vampire - Loren - 10000 - 3 - 28 - 59
20003 - Leprechaun - Claretta - 10000 - 48 - 64 - 97
20000 - Witch - Catheryn - 10000 - 5 - 77 - 98
20001 - Kobold - Kim - 10000 - 60 - 42 - 208
10001 - Gaggle//Party for refference
20004 - Elf - Bob - 10001 - 51 - 51 - 155
20006 - Yeti - Soraya - 10001 - 28 - 30 - 209
20007 - Pixie - Dusty - 10001 - 8 - 74 - 242
20005 - Hero - Sol - 10001 - 90 - 24 - 273
10002 - Gang
...
This is the Comparator for Empathy: (the 5th Int in the 5th column is Empathy)
public static class CEmpathy implements Comparator< Creature > {
@Override
public int compare( Creature o1, Creature o2 ) {
int c1 = o1.getEmpathy();
int c2 = o2.getEmpathy();
System.out.println( c1 + " & " + c2 );
if ( c1 < c2 ) return -1;
else if ( c1 == c2 ) return 0;
else return 1;
}
}
What confuses me is that the Comparator seems to execute properly, this a print out of each pair of numbers being compared.
60 & 5
3 & 60
3 & 60
3 & 5
48 & 5
48 & 60
90 & 51//new party
28 & 90
28 & 90
28 & 51
8 & 51
8 & 28
...
I have been at this for 2 hours printing at every step but everything seems to be executing properly. Any help would be greatly appreciated.
Upvotes: 1
Views: 423
Reputation: 85779
Noted by jlordo comment and answer, the problem was the lack of usage of the break
keyword at the end of each case
of your switch
statement. IMO you could move all this logic inside a Map<Integer, Comparator< Creature >>
and have each key mapped with the corresponding comparator you want/need. I'll post a basic example:
//sorry couldn't think of a better name for your class :)
public class ClassThatSortCreatures {
Map<Integer, Comparator<Creature>> mapComparators = new HashMap<Integer, Comparator<Creature>>();
public ClassThatSortCreatures() {
//initialize the map
mapCoparators.put(0, new compareThings.CEmpathy());
mapCoparators.put(1, new compareThings.CFear());
mapCoparators.put(2, new compareThings.CCarry());
}
public void SortCreatures ( int x ) {
for ( Party p : SorcerersCave.theCave.parties ) {
//avoiding usage of switch
Collections.sort( p.members, mapCoparators.get(x));
}
generateInterface.theGame.printOutput( "Displaying Sorted Creatures:" );
for ( Party p : SorcerersCave.theCave.parties ) {
generateInterface.theGame.printOutput( "" + p );
for ( Creature c : p.members ){
generateInterface.theGame.printOutput( "\t" + c );
}
}
}
}
And your code looks even cleaner and easier to maintain. Another tip to enhance this approach would be that instead of using an int
parameter you could use an enum
to avoid validating if the Comparator
exists in the map.
Upvotes: 2
Reputation: 1243
Your switch statement needs to be changed from
switch ( x ) {
case 0 :
Collections.sort( p.members, new compareThings.CEmpathy());
case 1 :
Collections.sort( p.members, new compareThings.CFear() );
case 2 :
Collections.sort( p.members, new compareThings.CCarry() );
}
to
switch ( x ) {
case 0 :
Collections.sort( p.members, new compareThings.CEmpathy());
break;
case 1 :
Collections.sort( p.members, new compareThings.CFear() );
break;
case 2 :
Collections.sort( p.members, new compareThings.CCarry() );
break;
}
Without the break statements, every line underneath the correct one will be executed as well. So if x was 2, everything would be sorted using CCarry(). If x was 1, everything would be sorted with CFear() and then CCarry(). If x is 0, the data is sorted by all three.
Upvotes: 0
Reputation: 37823
Don't forget the break
switch ( x ) {
case 0 :
Collections.sort( p.members, new compareThings.CEmpathy());
break; // IMPORTANT
case 1 :
Collections.sort( p.members, new compareThings.CFear());
break; // IMPORTANT
case 2 :
Collections.sort( p.members, new compareThings.CCarry());
break; // can be omitted here
}
because switch
cases are fall through, in your code the last statement will always be Collections.sort( p.members, new compareThings.CCarry());
as long as x
is either 0, 1 or 2.
Upvotes: 4