I have a list of string containing AA0 AA5 BB2 BB9 AA1 BB13 AA7 AA2
not in order. What I want is two seperate categories ordered like AA0 AA1 AA2 AA5 AA7 BB2 BB9 BB13
How could I do that?
I have tried myList.stream().sorted(mySorter).foreach(...);
where mySorter
like below:
private final Comparator<String> mySorter= ( o1, o2 ) -> {
try
{
final int first = Integer.parseInt( o1.substring( 2, o1.length() ) );
final int second = Integer.parseInt( o2.substring( 2, o2.length() ) );
System.out.println( o1 + " -> " + first + " " + o2 + " -> " + second );
if ( o1.contains( "AA" ) && o2.contains( "BB" ) )
{
return -1;
}
else if ( o1.contains( "AA" ) && o2.contains( "AA" ) )
{
return first - second;
}
else if ( o1.contains( "BB" ) && o2.contains( "BB" ) )
{
return first - second;
}
return first - second;
}
catch ( final Exception e )
{
e.printStackTrace();
return 0;
}
};
I am aware that it does contain unnecessarry if/else blocks but I am having java.lang.IllegalArgumentException: Comparison method violates its general contract!
at the same time which I have no idea why. Been trying to solve the exception and the algorithm could do what I want. Any help appreciated. Thanks.
Any comparator must follow these rules:
A<B
(as in, a.compareTo(b)
returns a negative number), then B>A
must be true (as in, if you were to call b.compareTo(a)
, it MUST return a positive number).A=A
(a.compareTo(a)
MUST return 0).A<B
and B<C
then this must hold: A<C
.That error means you aren't doing that.
It looks like you are stating that all AA categories precede all BB categories (via the line ( o1.contains( "AA" ) && o2.contains( "BB" ) )
, but you didn't add the reverse, where all BBs come after all AAs. You have to write it in pairs or it won't work. Fix that. Perhaps there are more violations, but, one step at a time.