开发者

Java sort based on two columns

Lets say I have table like this:

 String | Int1 | Int2
 "foo"    5      0
 "faa"    4      1
 "zaa"    0      1
 "zoo"    4      2
 "laa"    4      3
 "loo"    1      4

What I would like to get is table like this:

 String | Int1 | Int2
 "foo"    5      0
 "laa"    4      3
 "zoo"    4      2
 "faa"    4      1
 "loo"    1      4
 "zaa"    0      1

First thing that happens is sort based on column Int1.

Second thing that happens is sort of based on column Int2 but only on rows that have same numbers in column 开发者_StackOverflow中文版Int1

How should I approach this problem without using any database engine?


You'd normally do this with a List<Item> where Item is a type containing all three values ("foo", 5, 0 for the first row, for example).

You'd then write a Comparator<Item> which compared the Int1 values of the two Item objects presented to it in compare, and if that gave a definite answer, returned that answer... and otherwise compared the Int2 values.


I'm assuming you have an object that has a String with 2 ints?

The easiest way to do this is to make the object implement Comparable and implement the compareTo() method. Or you can pass a Comparator to Collections.sort(yourListOfObjects, yourCustomComparator)

The compareTo() method will compare the first int first and if they are equal compare the second ints.

@Override
public int compareTo(MyObject o) {
    // compare int1s .. if equal, compare int2s and return 0,1 or -1
}

Here is a helpful link

http://download.oracle.com/javase/tutorial/collections/interfaces/order.html


It's rather unclear what you mean by table. But in the general case, you sort data in Java by using a Comparator or making your data structure implement Comparable. In your case you would create a simple data structure that encapsulates a row in your table, and then create a Comparator for the row data structure or have it implement Comparable.

For example

public class Row implements Comparable<Row> {
    public final String theString;
    public final int int1;
    public final int int2;

    public Row(String theString, int int1, int int2) {
        this.theString = theString;
        this.int1 = int1;
        this.int2 = int2;
   }

   public int compareTo(Row other) {
       if(this.int1 == other.int1) {
           return new Integer(this.int2).compareTo(other.int2);
       }

       return new Integer(this.int1).compareTo(other.int1);
   }
}

Then you would create a List<Row> and use java.util.Collections.sort(List<?>) to sort your data.


If only Java supported lambdas ... this is trivial in so many languages.

But, hmm, let's see. Here are two general approaches (there are many different variations of these themes):

  1. Create a new type with the members in question
  2. Make the type implement Comparable (e.g. "compareTo")
  3. Put elements of this new type into an Array or List (perhaps List<NewType>)
  4. Use Arrays.sort or Collections.sort (or similar)

Or,

  1. Create a nested array or List (perhaps List<List<Object>>)
  2. Use Arrays.sort or Collections.sort (or similar) using the form that takes in a Comparator

Happy coding.


Well first define what you mean by a "table".

I would wrap each row within an object Row and keep an array of these Rows. Then you can either implement the Comparable<Row> interface or write your own Comparator<Row>.

So either:

...
class Row implements Comparable<Row> {
    String s;
    int int1, int2;

    ...

    public int compareTo( Row r ) {
        if( int1 != r.int1 ) return int1-r.int1;
        else return int2-r.int2;
    }
}

And call Arrays.sort(rows);

Or you can do this:

Arrays.sort(rows, new Comparator<Row>() {
    public int compare( Row r1, Row r2 ) {
        if( r1.int1 != r2.int1 ) return r1.int1-r2.int1;
        else return r1.int2-r2.int2;
    }
});

where rows is a Row[].


Something like this?

public class Item implements Comparable<Item> {
    private String s;
    private Integer int1;
    private Integer int2;

    @Override
    public int compareTo(Item o) {
        int compare = int1.compareTo(o.int1);
        return compare != 0 ? compare : int2.compareTo(o.int2);
    }
}


I would use a CompareToBuilder inside a Comparator implementation.

Example usage,

    new Comparator<YourObjectType>() {
            @Override
            public int compare(YourObjectType o1, YourObjectType o2) {
                return new CompareToBuilder()
                   .append(o1.firstFieldToCompare, o2.firstFieldToCompare)
                   .append(o1.secondFieldToCompare, o2.secondFieldToCompare)
                   .toComparison();
            }
        }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜