Reputation: 371
I have an made of colors. What I am trying to do is to sort the array from lowest in RGB colors to highest in RGB colors. I tried using Arrays.sort()
but its not a comparable that Arrays.sort()
can handle. How can I do this?
System.out.println("anchors unsorted: " + Arrays.toString(allAnchorColors));
Arrays.sort(allAnchorColors);
System.out.print("anchors sorted: " + Arrays.toString(allAnchorColors));
output:
anchors unsorted: [java.awt.Color[r=255,g=186,b=34], java.awt.Color[r=255,g=14,b=20], java.awt.Color[r=2,g=255,b=168], java.awt.Color[r=242,g=231,b=255], java.awt.Color[r=255,g=26,b=28], java.awt.Color[r=0,g=65,b=255]]
Upvotes: 1
Views: 4705
Reputation: 99
This isn't the only way to solve the problem but it's pehaps the most direct. Transform each color into HSV space and then order them by Hue (H). See this page for an explanation and demonstration. An algorithm to go from RGB to HSV is given on this page. Something like this
public class RGBtoHSV {
float r;
float g;
float b;
public RGBtoHSV(int red, int green, int blue) {
//Scale to float from 8 bit RGB values
r = red/255;
g = green/255;
b = blue/255;
}
public int[] getHSV() {
float cmax = Math.max(r, Math.max(g, b));
float cmin = Math.min(r, Math.min(g, b));
float deltaC = cmax - cmin;
float h;
if (cmax==r) {
h = (((g-b)/deltaC)%6)*60;
} else if (cmax==g) {
h = (((b-r)/deltaC) + 2)*60;
} else {
h = (((r-g)/deltaC) + 4)*60;
}
float s = 0;
if (cmax!=0) {
s = deltaC/cmax;
}
int[] returnValue = new int[3];
// re-scale
returnValue[0] = (int) h/255;
returnValue[1] = (int) s/255;
returnValue[2] = (int) cmax/255;
return returnValue;
}
With the integer h value, choose a starting point h value (as with the cheese wedge in the first link). Then increment (or decrement) mod 256 to get them in order.
Upvotes: 0
Reputation: 347184
The question is not an easy one to answer directly because Color
is made up of at least three primary properties (not including alpha ;)), but indirectly, you need to supply a custom Comparator
which can sort the colors based on your requirements, for example.
This basically makes use of the getRGB
method which converts the value into a packed int
value, making the comparison simpler
Color[] colors = {Color.RED, Color.GREEN, Color.BLUE, Color.BLACK, Color.WHITE};
for (Color color: colors) {
System.out.println(color.getRGB() + "; " + color);
}
Arrays.sort(colors, new Comparator<Color>() {
@Override
public int compare(Color o1, Color o2) {
return o1.getRGB() - o2.getRGB();
}
});
System.out.println("After");
for (Color color: colors) {
System.out.println(color.getRGB() + "; " + color);
}
Which prints out...
-65536; java.awt.Color[r=255,g=0,b=0]
-16711936; java.awt.Color[r=0,g=255,b=0]
-16776961; java.awt.Color[r=0,g=0,b=255]
-16777216; java.awt.Color[r=0,g=0,b=0]
-1; java.awt.Color[r=255,g=255,b=255]
After
-16777216; java.awt.Color[r=0,g=0,b=0]
-16776961; java.awt.Color[r=0,g=0,b=255]
-16711936; java.awt.Color[r=0,g=255,b=0]
-65536; java.awt.Color[r=255,g=0,b=0]
-1; java.awt.Color[r=255,g=255,b=255]
This "kind of" meets your requirements, in the fact that BLACK
is before WHITE
:P
However, the answer remains the same, you need to supply a custom Comparator
which generates the required result when comparing two values based on your algorithm for sorting
I am looking at this but am a little confused because when I implemented what you had here I got a bunch of other colors which I didn't have before
Based on the available information you've been able to provide me, the sort algorithm isn't adding any new values...
Color[] allAnchorColors = {
new Color(255, 200, 63),
new Color(255, 8, 12),
new Color(0, 255, 148),
new Color(223, 214, 255),
new Color(255, 19, 19),
new Color(0, 76, 255),
};
System.out.println("anchors.length = " + allAnchorColors.length);
System.out.println("anchors unsorted: " + Arrays.toString(allAnchorColors));
Arrays.sort(allAnchorColors, new Comparator<Color>() {
@Override
public int compare(Color o1, Color o2) {
return o1.getRGB() - o2.getRGB();
}
});
System.out.println("anchors.length = " + allAnchorColors.length);
System.out.print("anchors sorted: " + Arrays.toString(allAnchorColors));
Which outputs...
anchors.length = 6
anchors unsorted: [java.awt.Color[r=255,g=200,b=63], java.awt.Color[r=255,g=8,b=12], java.awt.Color[r=0,g=255,b=148], java.awt.Color[r=223,g=214,b=255], java.awt.Color[r=255,g=19,b=19], java.awt.Color[r=0,g=76,b=255]]
anchors.length = 6
anchors sorted: [java.awt.Color[r=0,g=76,b=255], java.awt.Color[r=0,g=255,b=148], java.awt.Color[r=223,g=214,b=255], java.awt.Color[r=255,g=8,b=12], java.awt.Color[r=255,g=19,b=19], java.awt.Color[r=255,g=200,b=63]]BUILD SUCCESSFUL (total time: 4 seconds)
which means, there is something in you code which you're not showing us that's causing the issue
Upvotes: 2
Reputation: 6019
This is how I got the result, Simply sorting them as String values,
String[] arr = {"java.awt.Color[r=255,g=186,b=34]", "java.awt.Color[r=255,g=14,b=20]", "java.awt.Color[r=2,g=255,b=168]", "java.awt.Color[r=242,g=231,b=255]","java.awt.Color[r=255,g=26,b=28]","java.awt.Color[r=0,g=65,b=255]"};
java.util.Arrays.sort(arr);
for (String string : arr) {
System.out.println(string);
}
Edit 1:
for (Color color : colorArray) {
String strColorValue = String.valueOf( color );
//Make a new arraylist and append strColorValue to it.
//Sort the list as above.
}
Upvotes: 2