1

Let me explain the scenario first:

List<Row> rowValues = new ArrayList<>();

// After adding values into list
At location 0 = [Johnson, 10000]
At location 1 = [Adam, 12000]
At location 2 = [Mike, 11000]
At location 3 = [Johnson, 17000]
At location 4 = [Tony, 10000]

I want to sort elements of column1 in ascending order and elements of column2 in descending order. Like:

At location 0 = [Adam, 12000]
At location 1 = [Johnson, 17000]
At location 2 = [Johnson, 10000]
At location 3 = [Mike, 11000]
At location 4 = [Tony, 10000]

I am not sure whether this can achieve this by using:

Collections.sort(rowValues); //or
Collections.sort(rowValues, Collections.reverseOrder());

Row class, if that makes any sense:

final class Row extends ArrayList<Object> implements Comparable<Row> {

    private int index;
    private Order order;


    Row(int initialCapacity) {
        super(initialCapacity);
        this.index = -1; //-1 indicates that the index has not been set
    }

    Object getSortingValue() {
        if (index == -1) {
            throw new IllegalStateException("Sorting column is unknown");
        } else if (isEmpty()) {
            throw new IllegalStateException("Row is empty");
        }
        return get(index);
    }

   void setSortingColumn(int index) throws IllegalArgumentException {
        if (index < 0) {
            throw new IllegalArgumentException("Invalid sorting index: " + index);
        }
        this.index = index;
    }

    Order getOrder() {
        return order;
    }

    void setOrder(Order order) {
        this.order = order;
    }

    @Override
    public int compareTo(Row row) {
        if (row == null) {
            throw new NullPointerException();
        }
        Object sortValue = getSortingValue();
        if (sortValue instanceof Comparable) {
            return ((Comparable) sortValue).compareTo(row.getSortingValue());
        } else {
            throw new IllegalArgumentException(sortValue + " not type of Comparable");
        }
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof Row) {
            Row row = (Row) obj;
            return getSortingValue().equals(row.getSortingValue());
        }
        return false;
    }

    @Override
    public int hashCode() {
        return getSortingValue().hashCode();
    }
}
ADTC
  • 8,999
  • 5
  • 68
  • 93
Script_Junkie
  • 277
  • 2
  • 6
  • 17
  • Create your own class that implements `Comparator`. You can have it define the order you want. – rgettman Jan 31 '14 at 00:44
  • @Lucky_Singh If you edit your post with your `Row` class, I can update my answer with code to achieve what you want. – Hugo Sousa Jan 31 '14 at 00:52
  • @HugoSousa Row class added. – Script_Junkie Jan 31 '14 at 00:56
  • @Lucky_Singh What are the printed values? (the name and the number?). It looks like there's already a `compareTo` defined. Wasn't you doing this code? – Hugo Sousa Jan 31 '14 at 01:00
  • @HugoSousa the printed values are Name and Salary, the compareTo() code sorts only 1 column, Name...but not the second one.. – Script_Junkie Jan 31 '14 at 01:02
  • @Lucky_Singh Ok, but I don't have access to those things, from the `Row` class, then. I guess you know what to do now, anyway. Here's an example pretty similar to yours, if that helps: http://stackoverflow.com/questions/14154127/collections-sortlistt-comparator-super-t-method-example – Hugo Sousa Jan 31 '14 at 01:06

3 Answers3

5

Yes, you can sort it using Collections.sort(), but you need to define your own Comparator, where you define that an object is bigger than other when the first row is bigger, or if they are equal, the second row is bigger.

Hugo Sousa
  • 1,904
  • 2
  • 15
  • 28
1

You need to account for 2 values(for both columns) in compareTo() method, Assuming that corresponding field in the Row object are named name and point -

 public int compareTo(Row row) {
        if(!name.equals(row.getName()){
        return name.compareTo(row.getName());
        }
         return  -1 * point.compareTo(row.getPoint());
    }
user1339772
  • 783
  • 5
  • 19
  • Should it be `return -1 * point.compareTo(row.getPoint());` since OP wants the second column in descending order? Or is it possible to specify the order dynamically? – ADTC Jan 31 '14 at 01:45
  • Thank you - edited my answer. The idea was to just show that compareTo() needs to account for 2 properties. We never know what point is - assuming its a String, I have edited the answer so that it is clear on first look. – user1339772 Jan 31 '14 at 01:47
  • Actually, I think it could be dynamic, using some operator. Not sure but take a look at [this](http://stackoverflow.com/a/14154534/1134080). *You also don't need the `equals` since `compareTo` can return `0`, as in that code.* – ADTC Jan 31 '14 at 01:52
0

I think you want to sort by name asc, and if the name is equal to another, then sort by value desc. If so, then

    List<Row> rowValues = new ArrayList<Row>();

    // After adding values into list
    rowValues.add(new Row("Johnson", 10000));
    rowValues.add(new Row("Adam", 12000));
    rowValues.add(new Row("Mike", 11000));
    rowValues.add(new Row("Johnson", 17000));
    rowValues.add(new Row("Tony", 10000));

    Collections.sort(rowValues, new RowComparator());

    System.out.println(rowValues);

and

public class Row {
    private String name;
    private Integer val;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getVal() {
        return val;
    }
    public void setVal(Integer val) {
        this.val = val;
    }
    public Row(String name, Integer val) {
        super();
        this.name = name;
        this.val = val;
    }
    @Override
    public String toString() {
        return "Row [name=" + name + ", val=" + val + "]";
    }

}

and

import java.util.Comparator;

public class RowComparator implements Comparator<Row> {

    public int compare(Row o1, Row o2) {
        if (o1.getName().equals(o2.getName())) {
            return -1 * o1.getVal().compareTo(o2.getVal());
        } else {
            return o1.getName().compareTo(o2.getName());
        }
    }

}
Leo
  • 6,480
  • 4
  • 37
  • 52