2

I have this class:

public class Sample implements Comparable<Sample> {
public String a;
public String b;
public String c;

public int compareTo (Sample sampleToCompare) {
int compResult = this.a.compareTo(sampleToCompare.a);
      return (compResult != 0 ? compResult : 
                   this.b.compareTo(sampleToCompare.b));    
    }
}

I want compareTo() to behave or sort using different class properties depending if a flag is set.

So, if flag == 1 I'd like compareTo() to using property c, otherwise is flag == 0, whatever is currently in the method.

In other words, sort the same class in different ways.

I am not sure how to achieve this. Please help.

Also, please let me know if more information is needed from my side.

3 Answers3

4

If you want to implement different kind of sorting, you should take a look at java.util.Comparator interface.

public class SampleComparatorA implement Comparator<Sample> {

    public int compare(Sample a, Sample b) {
        // Your sorting
    }
}

And use java.util.Collections.sort() method with the Comparator as the secound parameter instead.

Collections.sort(aSampleList, new SampleComparatorA());
user802421
  • 7,465
  • 5
  • 40
  • 63
  • There's a related example [here](http://stackoverflow.com/questions/5064027/sorting-2d-array-of-string-in-java/5064357#5064357). – trashgod Jul 17 '11 at 01:45
3

How about:

public int compareTo(Sample sampleToCompare) {
    if (flag == 1) {
        return this.c.compareTo(sampleToCompare.c);
    }
    if (flag == 0) {
        // current stuff
    }
    ...
}

That's not a very object-oriented way to do it, though. Probably you should have two different comparators and a way to select them based on your "flag" value. Something like:

class Sample {
    private String a;
    private String b;
    private String c;
}

class ASampleComparator implements Comparator<Sample> {
    public int compare(Sample o1, Sample o2) {
        return o1.a.compareTo(o2.a);
    }
}

class BSampleComparator implements Comparator<Sample> {
    public int compare(Sample o1, Sample o2) {
        return o1.b.compareTo(o2.b);
    }
}

class CSampleComparator implements Comparator<Sample> {
    public int compare(Sample o1, Sample o2) {
        return o1.c.compareTo(o2.c);
    }
}

public Comparator<Sample> pickComparator(int flag) {
    switch (flag) {
        case 0:
            return new ASampleComparator();
        case 1:
            return new BSampleComparator();
        case 2:
            return new CSampleComparator();
        default:
            throw new IllegalArgumentException("Bad flag value: " + flag);
    }
}
Ryan Stewart
  • 126,015
  • 21
  • 180
  • 199
1

You should make your flag static so the comparison will be consistent (as described in Effective Java, item 12), otherwise, you might get that a.compareTo(b) returns that a > b, but b.compareTo(a) returns that b > a. So the simplest implementation I can think about is:

public class Sample implements Comparable<Sample> {
public String a;
public String b;
public String c;
public static boolean my_flag = false;

public int compareTo (Sample sampleToCompare) {
    if (flag) {
        return this.c.compareTo(sampleToCompare.c);
    }
    int compResult = this.a.compareTo(sampleToCompare.a);
      return (compResult != 0 ? compResult : 
                   this.b.compareTo(sampleToCompare.b));    
    }
}
MByD
  • 135,866
  • 28
  • 264
  • 277
  • I don't buy the `static` part. `final`: yes. `static`: not necessary. – Jason S Jul 17 '11 at 01:34
  • @Jason - why would you make it final, if it might change? And why not static? I would really like an answer, as I might be missing something. – MByD Jul 17 '11 at 01:39
  • #MByD: my bad, I was thinking about `Comparator`, not `Comparable`, where you might want to have different ones. As for `final`, you really don't want to stick objects as keys in a `TreeMap` and change the rules midstream. – Jason S Jul 17 '11 at 01:41