Win a copy of Re-engineering Legacy Software this week in the Refactoring forum
or Docker in Action in the Cloud/Virtualization forum!

# help with custom COMPARATOR please

Nigel Shrin
Ranch Hand
Posts: 140
Hi
This is my first attempt at a comparator and its not quite right. I pass an integer to Lagrange4sq and it returns all the combinations of squares that sum to that number as a set of 1-4 numbers. (Pythagoras & Lagrange Theorem). The Lagrange4sq class is working fine and the results are stored in these objects; same data in two different formats:
public class Lagrange4sq {
...
eg of Formats:
orderedResultsRaw for 100: orderedResultsFormatted for 100:
5 5 5 5 [5,5,5,5]
7 5 5 1 etc
7 7 1 1
8 4 4 2
8 6
9 3 3 1
10

I want to try and output these in a specific sort order, results found in 1 sorted descending, results found in 2 sorted descending etc ie [10][8,6][9,3,3,1][8,4,4,2][7,7,1,1][7,5,5,1][5,5,5,5], so I've created this comparator object.
Bear in mind what I am trying to sort by is a string within a StringBuilder within a LinkedHashMap. In the comparator I am scaling up the first integer and subtracting other integers, so [10] will come first etc.

ATTEMPT TO USE COMPARATOR: (if I use an iterator in this method it works, but not with my desired sort)

ERROR: The method sort(T[], Comparator<? super T>) in the type Arrays is not applicable for the arguments (String, LagrangeComparator)

Thank you, Nigel

Gaurangkumar Khalasi
Ranch Hand
Posts: 187
Nigel Shrin wrote:ERROR: The method sort(T[], Comparator<? super T>) in the type Arrays is not applicable for the arguments (String, LagrangeComparator)

You have to pass String[] rather than String in the method "Arrays.sort(java.lang.Object[], java.util.Comparator)".

Nigel Shrin
Ranch Hand
Posts: 140
I've made changes and now have a string[] for the code calling the comparator:

This contains contents ok:
Size: 7
5 5 5 5
7 5 5 1
7 7 1 1
8 4 4 2
8 6
9 3 3 1
10
When I enable the Comparator line above I get very strange results, nulls and duplicates (no errors):
Size: 7 (followed by three blank rows) then 5 5 5 5 etc

5 5 5 5
7 7 1 1
8 6
8 6

But no code inside the comparator is actually running, its just losing data.

Is the compare correct?
Many thanks! Nigel>

Gaurangkumar Khalasi
Ranch Hand
Posts: 187
Nigel Shrin wrote:Is the compare correct?

Yes it is.
I have done some work please check it and may be it will helpful to you?
Output is:

Check the sorting order for Strings...

Nigel Shrin
Ranch Hand
Posts: 140
Hi Gaurangkumar,

Thanks for testing the sort, it does achieve a sort of 10, 5 5 5 5, 7 7 1 9, 7 7 5 1, 8 6 but I am trying to achieve a sort of [10][8,6][9,3,3,1][8,4,4,2][7,7,1,1][7,5,5,1][5,5,5,5]
ie a one number set where the square equals 100, followed by a two number set where the square equals 10, if there is more than one set of three numbers subsort the list, and finally four number sets. For value 100 there are no three number solutions, but many four number solutions.
When I say "no code inside the comparator is actually running" the compare() is running but toNumeric() is not being used, and it is this that should achieve the custom sort (in theory!).

I am thinking I need to override .equals ??? not sure. Thanks again!>

Gaurangkumar Khalasi
Ranch Hand
Posts: 187

Why do you want to override equals()? It will be used to check content equality of two objects. In your example, i don't think there is a need of it!!!

Nigel Shrin
Ranch Hand
Posts: 140
Hi Gaurangkumar,

the crux of the required sort, is the scaling of the individual elements in each string array:
if(i == 0) tot = tot + (Long.valueOf(strAry[i])*100000);
if(i == 1) tot = tot + (Long.valueOf(strAry[i])*-1);
if(i == 2) tot = tot + (Long.valueOf(strAry[i])*-100);
if(i == 3) tot = tot + (Long.valueOf(strAry[i])*-10000);

Why are these lines not being accessed/applied?
For as long as that is the case the output will be a mundane standard String sort.

I agree the attempt to call toNumeric did not resolve the above key issue, but the above is what I need to understand, why is not being called?

Thanks

Gaurangkumar Khalasi
Ranch Hand
Posts: 187
Nigel Shrin wrote:Why are these lines not being accessed/applied?

They are called...If you want to check than put if(...){System.out.println("Check...")}...
Try out following updated version code of yours...i have changed just "return toNumeric(str2).compareTo(toNumeric(str1));"...i think it gives you, your required result...
Output:

Nigel Shrin
Ranch Hand
Posts: 140
Hi Gaurangkumar,
Well done! that was the key!! just str1 & str2 the wrong way around, I didn't realise I was so close. It didn't enter toNumeric() with other way around.
Once I was in toNumeric() I could tweak the maths to scale up to obtain the desired sort, and I now have it working:

Results:
Cmp applied: 10
Cmp applied: 9
Cmp applied: 10 3
Cmp applied: 10 1
Cmp applied: 9 4
Cmp applied: 9 3
Cmp applied: 8 6
Cmp applied: 8 1
Cmp applied: 10 3 1
Cmp applied: 9 3 1
Cmp applied: 8 3 1
Cmp applied: 7 7 9
Cmp applied: 7 7 1
Cmp applied: 9 3 3 1
Cmp applied: 8 4 4 2
Cmp applied: 7 7 5 2
Cmp applied: 7 6 1 9
Cmp applied: 5 5 5 5
Cmp applied: 5 5 4 5