2

I've got this class called Block (each Block has an x value and a y value). I've created a bunch of these and put them all in a list. I've managed to sort the list by x-value:

public class Block implements Comparable<Block> {
...
public int compareTo(Block block2){
    return this.x - block2.x;
}

But I want to be able to sort the list both by x and by y-value at my leisure. Is this doable somehow?

2
  • What is the sort condition when involves both x and y value? Commented Aug 27, 2013 at 14:48
  • 1
    Use a Comparator<Block> instead of the default compareTo(method) (and of course the right sort method that uses the Comparator<Block>) Commented Aug 27, 2013 at 14:49

4 Answers 4

4

You can implement two Comparators:

enum BlockSort implements Comparator<Block> {
    XSORT {
        @Override
        public int compare(Block b1, Block b2) {
            return b1.x - b2.x;
        }
    },

    YSORT {
        @Override
        public int compare(Block b1, Block b2) {
            return b1.y - b2.y;
        }
    }
}

Then pass the appropriate instance XSORT/YSORT as a second argument to the sort method. For example:

Collections.sort(blockList, BlockSort.XSORT);

Additionally, if by-x isn't the natural ordering of Block instances, it would likely be wiser to not make Blocks Comparable at all.

Sign up to request clarification or add additional context in comments.

3 Comments

Why are there 2 separate enums?
@JoshM We only will ever need a single instance of XSort/YSort, so we can make them enums where INSTANCE is this single instance. Or are you saying we could put both in a single enum?
I was thinking of a single enum. See my answer, although I think JNL beat me to it. :(
2

You can use 2 Comparators to achieve this.

public class XComparator implements COmparator<Block>{
  public int compare(T o1, T o2){
    ...
  }
}

and :

public class YComparator implements COmparator<Block>{
  public int compare(T o1, T o2){
    ...
  }
}

Then use one of them to sort:

Collections.sort(list, new XComparator());
Collections.sort(list, new YComparator());

Comments

1

Much like @arshajii's answer, you could utilize an enum for the various different sorting methods, code shown below:

public enum BlockSorting implements Comparator<Block> {
    X{
        public int compare(final Block b1, final Block b2){
            return b1.x - b2.x;
        }
    },
    Y{
        public int compare(final Block b1, final Block b2){
            return b1.y - b2.y;
        }
    };
}

The advantage to using this way is that you could easily add more sorting methods (without creating a new enum each time). For example, to sort the collection of Blocks using the X, you could do something like this:

Collection<Block> blocks = ....;
Collections.sort(blocks, BlockSorting.X);

1 Comment

I was just updating my answer to use a single enum. +1 anyway.
0

A solution with Enums;

public static enum Order implements Comparator {
     ByX() {
        public int compare(Block b1, Block b2) {
           return b1.x - b2.x;
        }
     },

     ByY() {
        public int compare(Block b1, Block b2) {
           // TODO: Should really use a collator.
           return b1.y - b2.y;
        }
};

Then you call it by,

Collections.sort(blocks, Order.ByX);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.