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();
    }
}
6
  • Create your own class that implements Comparator<Row>. You can have it define the order you want. Commented Jan 31, 2014 at 0:44
  • @Lucky_Singh If you edit your post with your Row class, I can update my answer with code to achieve what you want. Commented Jan 31, 2014 at 0:52
  • @HugoSousa Row class added. Commented Jan 31, 2014 at 0: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? Commented Jan 31, 2014 at 1:00
  • @HugoSousa the printed values are Name and Salary, the compareTo() code sorts only 1 column, Name...but not the second one.. Commented Jan 31, 2014 at 1:02

3 Answers 3

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.

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

Comments

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());
    }

3 Comments

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?
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.
Actually, I think it could be dynamic, using some operator. Not sure but take a look at this. You also don't need the equals since compareTo can return 0, as in that code.
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());
        }
    }

}

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.