Hey, I need to sort an array list of class house by a float field in a certain range. This is my code for the selection sort:
Basically sortPrice copies the stuff in this list into a new one selecting only the values in that range, then it does a selection sort in that array list. The arraylist (x) in sortPrice is unsorted an needs to be copied because what x references cannot be altered.
public ArrayList<House> sortPrice(ArrayList<House> x,float y, float z){
ArrayList<House> xcopy = new ArrayList<House>();
for(int i = 0; i<x.size(); i++){
if(x.get(i).myPriceIsLessThanOrEqualTo(z) && x.get(i).myPriceIsGreaterThanOrEqualTo(y)){
xcopy.add(x.get(i));
}
}
ArrayList<House> price= new ArrayList<House>();
while(xcopy.size()>0){
House min = xcopy.get(0);
for(int i = 1; i < xcopy.size();i++){
House current = xcopy.get(i);
if (current.myPriceIsGreaterThanOrEqualTo(min.getPrice())){
min = current;
}
}
price.add(min);
xcopy.remove(min);
}
return price;
}
Here is what the house class looks like:
public class House {
private int numBedRs;
private int sqft;
private float numBathRs;
private float price;
private static int idNumOfMostRecentHouse = 0;
private int id;
public House(int bed,int ft, float bath, float price){
sqft = ft;
numBathRs = bath;
numBedRs = bed;
this.price = price;
idNumOfMostRecentHouse++;
id = idNumOfMostRecentHouse;
}
public boolean myPriceIsLessThanOrEqualTo(float y){
if(Math.abs(price - y)<0.000001){
return true;
}
return false;
}
public boolean myPriceIsGreaterThanOrEqualTo(float b){
if(Math.abs(b-price)>0.0000001){
return true;
}
return false;
}
When i call looking for houses in range 260000.50 to 300000 I only get houses that are at the top of the range even though I have a lower value at 270000. Can someone help?
You should use rounded double type.
DecimalFormat p= new DecimalFormat( "#0.00" );
double price = 123.00001;
price = new Double(p.format(price)).doubleValue();
Your method name indicates it sorts the data, the method also filters. You need to change the name. Actually there are a number of variables in this code which need their names change to better reflect what they contain.
You need to replace the for loops with for-each loops. That will simply and make the code clearer. You would also no longer need the while() statement.
I would also refactor the mypriceis... methods into a single ispriceinrange method.
Alternatively I'd look at the comparator interface and look at introducing it as a way to sort you data without having to hand code a loop.
Just took a second look. You do actually sort in the second loop, but that some ugly code and probably won't perform well to boot. Definitely go look at comparator and Collections.sort() methods. Save yourself a world of pain.
The best data structure for this problem would be a NavigableMap<Float,List<House>> (such as a TreeMap), which supports a subMap operation:
SortedMap<K,V> subMap(K fromKey, K toKey) : Returns a view of the portion of this map whose keys range from fromKey, inclusive, to toKey, exclusive.
There is also an overload that allows you to set inclusive bounds.
Here's a demonstration:
NavigableMap<Integer,String> nmap = new TreeMap<Integer,String>();
nmap.put(5, "Five");
nmap.put(1, "One");
nmap.put(7, "Seven");
nmap.put(3, "Three");
System.out.println(nmap.subMap(2, 6));
// prints {3=Three, 5=Five}
For your case, you'd want to either make House implementsComparable<House>, or define your own custom Comparator<House>. You'd then let TreeMap do the sorting for you, and don't have to deal with selection sort (which, at O(N^2), is far from optimal).
If you're stuck with the specification that you're given, then I'd suggest breaking apart the logic into helper methods like these:
List<House> filterInRange(List<House> houses, float low, float high) {
List<House> ret = new ArrayList<House>();
for (House h : houses) {
if (isInRange(h.getPrice(), low, high)) {
ret.add(h);
}
}
return ret;
}
static boolean isInRange(float v, float low, float high) { ...DIY... }
void selectionSort(List<House> houses) { ...Wikipedia... }
Then to get a sorted List<House> in a specified price range, invoke filterInRange and then selectionSort the returned list.
See also
Java language guide/for-each
Related
I want to build some sort of array that will store the note names e.g. A4 and it's frequency e.g. 440
I also want to know what sort of class I should use to do this.
I want to be able to use a wave generator class to generate that note as a waveform like a Sine or square wave. Example
public SineGenerator(double amplitude, Note note, int bitRate, double duration) {
SineGenerator sg = new SineGenerator(0.8, C4(or middle C, 261.63Hz), 16, 1);
The Note class will index C4 in some sort of array and then return Middle C's frequency, 261.63 to the SineGenerator and SineGenerator will generate the sine wave.
If I understood correctly, you are asking for a rough guide of how to implement the Note class.
The Note class will probably contain 3 main fields:
private char letter;
private int octave;
private boolean sharp;
A note such as D♭4 will have a letter of C, octave of 4 and a sharp of true. As you can see, I am representing D♭ and C# as the same note here, as they have the same frequency, and the only thing of importance here seems to be the frequency.
Note will also have a HashMap<String, Double> or HashMap<String, Integer> to store the frequency of each note. Note that you don't need to store the semitones in this map, as you can just multiply the note below by 1.0595 (or Math.pow(2, 1.0 / 12)) to get the semitone frequency.
And then you'd write a method called getFrequency, which accesses the map. If sharp is true, multiply it by 1.0595 and return.
Here's a simple implementation that I have written:
class Note {
private char letter;
private int octave;
private boolean sharp;
private static HashMap<String, Integer> map;
static {
map = new HashMap<>();
map.put("C0", 16);
map.put("D0", 18);
map.put("E0", 21);
map.put("F0", 22);
map.put("G0", 25);
map.put("A1", 28);
// ...
}
public Note(char letter, int octave, boolean sharp) {
this.letter = letter;
this.octave = octave;
this.sharp = sharp;
}
public char getLetter() {
return letter;
}
public int getOctave() {
return octave;
}
public boolean isSharp() {
return sharp;
}
public double getFrequency() {
String key = Character.toString(letter) + octave;
double frequency = map.get(key);
if (sharp) {
frequency *= Math.pow(2, 1.0 / 12);
}
return frequency;
}
}
For storing the note names and their respective frequency, look up HashMaps, it sounds like what you're looking for.
Use the note names as Key and the frequencies as Value.
HashMap<String, Double> Notes = new HashMap<>();
I am having a hard time understanding the right syntax to sort Maps which values aren't simply one type, but can be nested again.
I'll try to come up with a fitting example here:
Let's make a random class for that first:
class NestedFoo{
int valA;
int valB;
String textA;
public NestedFoo(int a, int b, String t){
this.valA = a;
this.valB = b;
this.textA = t;
}
}
Alright, that is our class.
Here comes the list:
HashMap<Integer, ArrayList<NestedFoo>> sortmePlz = new HashMap<>();
Let's create 3 entries to start with, that should show sorting works already.
ArrayList<NestedFoo> l1 = new ArrayList<>();
n1 = new NestedFoo(3,2,"a");
n2 = new NestedFoo(2,2,"a");
n3 = new NestedFoo(1,4,"c");
l1.add(n1);
l1.add(n2);
l1.add(n3);
ArrayList<NestedFoo> l2 = new ArrayList<>();
n1 = new NestedFoo(3,2,"a");
n2 = new NestedFoo(2,2,"a");
n3 = new NestedFoo(2,2,"b");
n4 = new NestedFoo(1,4,"c");
l2.add(n1);
l2.add(n2);
l2.add(n3);
l2.add(n4);
ArrayList<NestedFoo> l3 = new ArrayList<>();
n1 = new NestedFoo(3,2,"a");
n2 = new NestedFoo(2,3,"b");
n3 = new NestedFoo(2,2,"b");
n4 = new NestedFoo(5,4,"c");
l3.add(n1);
l3.add(n2);
l3.add(n3);
l3.add(n4);
Sweet, now put them in our Map.
sortmePlz.put(5,l1);
sortmePlz.put(2,l2);
sortmePlz.put(1,l3);
What I want now, is to sort the Entire Map first by its Keys, so the order should be l3 l2 l1.
Then, I want the lists inside each key to be sorted by the following Order:
intA,intB,text (all ascending)
I have no idea how to do this. Especially not since Java 8 with all those lambdas, I tried to read on the subject but feel overwhelmed by the code there.
Thanks in advance!
I hope the code has no syntatical errors, I made it up on the go
You can use TreeSet instead of regular HashMap and your values will be automatically sorted by key:
Map<Integer, ArrayList<NestedFoo>> sortmePlz = new TreeMap<>();
Second step I'm a little confused.
to be sorted by the following Order: intA,intB,text (all ascending)
I suppose you want to sort the list by comparing first the intA values, then if they are equal compare by intB and so on. If I understand you correctly you can use Comparator with comparing and thenComparing.
sortmePlz.values().forEach(list -> list
.sort(Comparator.comparing(NestedFoo::getValA)
.thenComparing(NestedFoo::getValB)
.thenComparing(NestedFoo::getTextA)));
I'm sure there are way of doing it with lambda but it is not actually required. See answer from Schidu Luca for a lambda like solution.
Keep reading if you want an 'old school solution'.
You cannot sort a map. It does not make sense because there is no notion of order in a map. Now, there are some map objects that store the key in a sorted way (like the TreeMap).
You can order a list. In your case, makes the class NestedFoo comparable (https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html). Then you can invoke the method Collections.sort (https://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#sort-java.util.List-) on your lists.
Use TreeMap instead of HashMap, it solves the 1st problem: ordering entries by key.
After getting the needed list from the Map, you can sort the ArrayList by valA, valB, text:
l1.sort(
Comparator.comparing(NestedFoo::getValA).thenComparing(NestedFoo::getValB).thenComparing(NestedFoo::getTextA)
);
And change your NestedFoo class definition like this:
class NestedFoo {
int valA;
int valB;
String textA;
public NestedFoo(int a, int b, String t) {
this.valA = a;
this.valB = b;
this.textA = t;
}
public int getValA() {
return valA;
}
public void setValA(int valA) {
this.valA = valA;
}
public int getValB() {
return valB;
}
public void setValB(int valB) {
this.valB = valB;
}
public String getTextA() {
return textA;
}
public void setTextA(String textA) {
this.textA = textA;
}
}
When using treemap for sorting keep in mind that treemap uses compareTo instead of equals for sorting and to find duplicity. compareTo should be incosistent with equals and hashcode when implemented for any object which will be used as key. You can look for a detailed example on this link https://codingninjaonline.com/2017/09/29/unexpected-results-for-treemap-with-inconsistent-compareto-and-equals/
I need a Collection that sorts the element, but does not removes the duplicates.
I have gone for a TreeSet, since TreeSet actually adds the values to a backed TreeMap:
public boolean add(E e) {
return m.put(e, PRESENT)==null;
}
And the TreeMap removes the duplicates using the Comparators compare logic
I have written a Comparator that returns 1 instead of 0 in case of equal elements. Hence in the case of equal elements the TreeSet with this Comparator will not overwrite the duplicate and will just sort it.
I have tested it for simple String objects, but I need a Set of Custom objects.
public static void main(String[] args)
{
List<String> strList = Arrays.asList( new String[]{"d","b","c","z","s","b","d","a"} );
Set<String> strSet = new TreeSet<String>(new StringComparator());
strSet.addAll(strList);
System.out.println(strSet);
}
class StringComparator implements Comparator<String>
{
#Override
public int compare(String s1, String s2)
{
if(s1.compareTo(s2) == 0){
return 1;
}
else{
return s1.compareTo(s2);
}
}
}
Is this approach fine or is there a better way to achieve this?
EDIT
Actually I am having a ArrayList of the following class:
class Fund
{
String fundCode;
BigDecimal fundValue;
.....
public boolean equals(Object obj) {
// uses fundCode for equality
}
}
I need all the fundCode with highest fundValue
You can use a PriorityQueue.
PriorityQueue<Integer> pQueue = new PriorityQueue<Integer>();
PriorityQueue(): Creates a PriorityQueue with the default initial capacity (11) that orders its elements according to their natural ordering.
This is a link to doc: https://docs.oracle.com/javase/8/docs/api/java/util/PriorityQueue.html
I need all the fundCode with highest fundValue
If that's the only reason why you want to sort I would recommend not to sort at all. Sorting comes mostly with a complexity of O(n log(n)). Finding the maximum has only a complexity of O(n) and is implemented in a simple iteration over your list:
List<Fund> maxFunds = new ArrayList<Fund>();
int max = 0;
for (Fund fund : funds) {
if (fund.getFundValue() > max) {
maxFunds.clear();
max = fund.getFundValue();
}
if (fund.getFundValue() == max) {
maxFunds.add(fund);
}
}
You can avoid that code by using a third level library like Guava. See: How to get max() element from List in Guava
you can sort a List using Collections.sort.
given your Fund:
List<Fund> sortMe = new ArrayList(...);
Collections.sort(sortMe, new Comparator<Fund>() {
#Override
public int compare(Fund left, Fund right) {
return left.fundValue.compareTo(right.fundValue);
}
});
// sortMe is now sorted
In case of TreeSet either Comparator or Comparable is used to compare and store objects . Equals are not called and that is why it does not recognize the duplicate one
Instead of the TreeSet we can use List and implement the Comparable interface.
public class Fund implements Comparable<Fund> {
String fundCode;
int fundValue;
public Fund(String fundCode, int fundValue) {
super();
this.fundCode = fundCode;
this.fundValue = fundValue;
}
public String getFundCode() {
return fundCode;
}
public void setFundCode(String fundCode) {
this.fundCode = fundCode;
}
public int getFundValue() {
return fundValue;
}
public void setFundValue(int fundValue) {
this.fundValue = fundValue;
}
public int compareTo(Fund compareFund) {
int compare = ((Fund) compareFund).getFundValue();
return compare - this.fundValue;
}
public static void main(String args[]){
List<Fund> funds = new ArrayList<Fund>();
Fund fund1 = new Fund("a",100);
Fund fund2 = new Fund("b",20);
Fund fund3 = new Fund("c",70);
Fund fund4 = new Fund("a",100);
funds.add(fund1);
funds.add(fund2);
funds.add(fund3);
funds.add(fund4);
Collections.sort(funds);
for(Fund fund : funds){
System.out.println("Fund code: " + fund.getFundCode() + " Fund value : " + fund.getFundValue());
}
}
}
Add the elements to the arraylist and then sort the elements using utility Collections.sort,. then implement comparable and write your own compareTo method according to your key.
wont remove duplicates as well, can be sorted also:
List<Integer> list = new ArrayList<>();
Collections.sort(list,new Comparator<Integer>()
{
#Override
public int compare(Objectleft, Object right) {
**your logic**
return '';
}
}
)
;
I found a way to get TreeSet to store duplicate keys.
The problem originated when I wrote some code in python using SortedContainers. I have a spatial index of objects where I want to find all objects between a start/end longitude.
The longitudes could be duplicates but I still need the ability to efficiently add/remove specific objects from the index. Unfortunately I could not find the Java equivalent of the Python SortedKeyList that separates the sort key from the type being stored.
To illustrate this consider that we have a large list of retail purchases and we want to get all purchases where the cost is in a specific range.
// We are using TreeSet as a SortedList
TreeSet _index = new TreeSet<PriceBase>()
// populate the index with the purchases.
// Note that 2 of these have the same cost
_index.add(new Purchase("candy", 1.03));
Purchase _bananas = new Purchase("bananas", 1.45);
_index.add(new Purchase(_bananas);
_index.add(new Purchase("celery", 1.45));
_index.add(new Purchase("chicken", 4.99));
// Range scan. This iterator should return "candy", "bananas", "celery"
NavigableSet<PriceBase> _iterator = _index.subset(
new PriceKey(0.99), new PriceKey(3.99));
// we can also remove specific items from the list and
// it finds the specific object even through the sort
// key is the same
_index.remove(_bananas);
There are 3 classes created for the list
PriceBase: Base class that returns the sort key (the price).
Purchase: subclass that contains transaction data.
PriceKey: subclass used for the range search.
When I initially implemented this with TreeSet it worked except in the case where the prices are the same. The trick is to define the compareTo() so that it is polymorphic:
If we are comparing Purchase to PriceKey then only compare the price.
If we are comparing Purchase to Purchase then compare the price and the name if the prices are the same.
For example here are the compareTo() functions for the PriceBase and Purchase classes.
// in PriceBase
#Override
public int compareTo(PriceBase _other) {
return Double.compare(this.getPrice(), _other.getPrice());
}
// in Purchase
#Override
public int compareTo(PriceBase _other) {
// compare by price
int _compare = super.compareTo(_other);
if(_compare != 0) {
// prices are not equal
return _compare;
}
if(_other instanceof Purchase == false) {
throw new RuntimeException("Right compare must be a Purchase");
}
// compare by item name
Purchase _otherPurchase = (Purchase)_other;
return this.getName().compareTo(_otherChild.getName());
}
This trick allows the TreeSet to sort the purchases by price but still do a real comparison when one needs to be uniquely identified.
In summary I needed an object index to support a range scan where the key is a continuous value like double and add/remove is efficient.
I understand there are many other ways to solve this problem but I wanted to avoid writing my own tree class. My solution seems like a hack and I am surprised that I can't find anything else. if you know of a better way then please comment.
Hi am trying to draw polygons on the map depending on the shortest distance.
i have created the array list called distancearray.
but i want to create a new array list called shortdistance, this array list must have the same values in the distancearray but it must be shorted in assending order depending on the distance.
can any one help me to create this shortdistance array. Thank you.
String array[][]=dbhand.collecting(getIntent().getExtras().getString("temple_type"), Integer.parseInt(getIntent().getExtras().getString("notemples")));
for(int i=0;i<array.length;i++){
displaymarkers(Double.parseDouble(array[i][0]), Double.parseDouble(array[i][1]), array[i][2]);
}
for(int i=0;i<array.length;i++){
double Distance = calculate_distance(SEATTLE_LAT, SEATTLE_LNG, Double.parseDouble(array[i][0]), Double.parseDouble(array[i][1]));
double[][] distancearray = new double[array.length][3];
distancearray[i][0]=Double.parseDouble(array[i][0]);
distancearray[i][1]=Double.parseDouble(array[i][1]);
distancearray[i][2]=Distance;
}
double [][] shortdistance = new double [array.length][3];
Draw Polygon Function
private void drawpolygon(String array[][]) {
int lengh = array.length;
if(lengh==2){
mMap.addPolygon(new PolygonOptions()
//.add(new LatLng(9.662502, 80.010239), new LatLng(9.670931, 80.013201), new LatLng(9.663216, 80.01333))
.add(new LatLng(9.6632139, 80.0133258))
.add(new LatLng(Double.parseDouble(array[0][0]), Double.parseDouble(array[0][1])))
.add(new LatLng(Double.parseDouble(array[1][0]), Double.parseDouble(array[1][1])))
.fillColor(Color.GRAY));
}
Just call Arrays.sort() against your array and specify a comparator that looks at the distance.
You are going to have difficulty sorting your arrays as-is because you currently store your data in parallel arrays:
distancearray[i][0]=Double.parseDouble(array[i][0]);
distancearray[i][1]=Double.parseDouble(array[i][2]);
distancearray[i][3]=Distance;
You can sort distancearray[n] but that will give you nonsense results. Instead what you should do is create a small class that implements Comparable (comparing based on distance) that holds your three values, then work with an array of those classes:
class DistanceInfo implements Comparable<DistanceInfo> {
public double a;
public double b;
public double distance;
public DistanceInfo (double a, double b, double distance) {
this.a = a;
this.b = b;
this.distance = distance;
}
#Override public int compareTo (DistanceInfo d) {
return Double.compare(distance, d.distance);
}
}
// then:
DistanceInfo[] distancearray = new DistanceInfo[array.length];
// and you can load it using the constructor:
for (int i = 0; i < array.length) {
double a = Double.parseDouble(array[i][0]);
double b = Double.parseDouble(array[i][1]);
distancearray[i] = new DistanceInfo(a, b, Distance);
}
(The fields can be made final if you wish to specify that they cannot be modified after construction.)
Now, Arrays.sort() will sort distancearray based on distance:
Arrays.sort(distancearray, null);
You could also use an ArrayList<DistanceInfo> instead, the idea is the same except you sort with Collections.sort().
In general, for this reason (among others) it is usually better to use a class to store all information about an object as opposed to parallel arrays.
As an aside, you may want to consider using this class for array as well, it will simplify your code a bit (you can modify displaymarkers to take a DistanceInfo, and you can also avoid parsing the same double more than once).
I need a sorted set of objects and am currently using the TreeSet. My problem is that the compareTo of the objects will often return 0, meaning the order of those two objects is to be left unchanged. TreeMap (used by TreeSet by default) will then regard them as the same object, which is not true.
What alternative to TreeMap can I use?
Use case: I have a set of displayable objects. I want to sort them by Y coordinate, so that they are rendered in the correct order. Of course, two objects may well have the same Y coordinate.
You're defining one criteria to compare, but you need to add extra criteria.
You say:
I have a set of displayable objects. I want to sort them by Y coordinate, so that they are rendered in the correct order. Of course, two objects may well have the same Y coordinate.
So, If two elements have the same Y coordinate, what you you put first? What would be the other criteria?
It may be the creation time, it may be the x coordinate, you just have to define it:
Map<String,Thing> map = new TreeMap<String,Thing>(new Comparator<Thing>(){
public int compare( Thing one, Thing two ) {
int result = one.y - two.y;
if( result == 0 ) { // same y coordinate use another criteria
result = one.x - two.x;
if( result == 0 ) { //still the same? Try another criteria ( maybe creation time
return one.creationTime - two.creationTime
}
}
return result;
}
});
You have to define when one Thing is higher / lower / equal / than other Thing . If one of the attributes is the same as other, probably you should not move them. If is there other attribute to compare the use it.
The issue you're running into is that compareTo returning 0 means that the objects are equal. At the same time, you're putting them into a set, which does not allow multiple copies of equal elements.
Either re-write your compareTo so that unequal elements return different values, or use something like a java.util.PriorityQueue which allows multiple copies of equal elements.
I've done this before. It's an ordered multi-map and it is just a TreeMap of List objects. Like this..
Map<KeyType, List<ValueType>> mmap = new TreeMap<KeyType, List<ValueType>>();
You need to construct a new LinkedList every time a new key is introduced, so it might be helpful to wrap it in a custom container class. I'll try to find something.
So, I threw this custom container together quickly (completely untested), but it might be what you are looking for. Keep in mind that you should only use this type of container if you are truly looking for an ordered map of value lists. If there is some natural order to your values, you should use a TreeSet as others have suggested.
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
public class MTreeMap<K, V> {
private final Map<K, List<V>> mmap = new TreeMap<K, List<V>>();
private int size = 0;
public MTreeMap() {
}
public void clear() {
mmap.clear();
size=0;
}
public boolean containsKey(K key) {
return mmap.containsKey(key);
}
public List<V> get(K key) {
return mmap.get(key);
}
public boolean isEmpty() {
return mmap.isEmpty();
}
public Set<K> keySet() {
return mmap.keySet();
}
public Collection<List<V>> valueLists() {
return mmap.values();
}
public void put(K key, V value) {
List<V> vlist = mmap.get(key);
if (null==vlist) {
vlist = new LinkedList<V>();
mmap.put(key, vlist);
}
vlist.add(value);
++size;
}
public List<V> remove(Object key) {
List<V> vlist = mmap.remove(key);
if (null!=vlist) {
size = size - vlist.size() ;
}
return vlist;
}
public int size() {
return size;
}
public String toString() {
return mmap.toString();
}
}
Here's a rudimentary test:
public class TestAnything {
public static void main(String[] args) {
MTreeMap<Integer, String> mmap = new MTreeMap<Integer, String>();
mmap.put(1, "Value1");
mmap.put(2, "Value2");
mmap.put(3, "Value3");
mmap.put(1, "Value4");
mmap.put(3, "Value5");
mmap.put(2, "Value6");
mmap.put(2, "Value7");
System.out.println("size (1) = " + mmap.get(1).size());
System.out.println("size (2) = " + mmap.get(2).size());
System.out.println("size (3) = " + mmap.get(3).size());
System.out.println("Total size = " + mmap.size());
System.out.println(mmap);
}
}
The output is this:
size (1) = 2
size (2) = 3
size (3) = 2
Total size = 7
{1=[Value1, Value4], 2=[Value2, Value6, Value7], 3=[Value3, Value5]}
I have one idea of my own, but it's more of a workaround
int compare(Object a, Object b) {
an = a.seq + (a.sortkey << 16); // allowing for 65k items in the set
bn = b.seq + (a.sortKey << 16);
return an - bn; // can never remember whether it's supposed to be this or b - a.
}
sortKey = what really matters for the sorting, for example an Y coordinate
seq = a sequence number assigned to objects when added to the set
There are 2 important things to remember when using sorted sets (e.g. TreeSet) :
1) They are sets; two equal elements are not allowed in the same collection
2) Equality must be consistent with the comparison mechanism (either comparator or comparable)
Therefore, in your case you should "break ties" by adding some secondary ordering criteria. For example: first use Y axis, then X, and then some unique object identifier.
See also http://eyalsch.wordpress.com/2009/11/23/comparators/