apoorvabade
apoorvabade

Reputation: 575

sort list based on an instance variable java

I have a list of order objects. Each order object has 5 instance variables. Is there a way I can sort this list based on any of these instace variables? I need to implement the comparable interface. But in that case, how could I sort on a specific variable?

Upvotes: 0

Views: 6192

Answers (5)

Eric Grindt
Eric Grindt

Reputation: 11

You can do this pretty elegantly in Scala.

val sortedOrders = orders.sortBy(o => (o.a, o.b, o.c))

Sorts the orders list by the the field a first, then by field b, and then by field c.

Upvotes: 1

camickr
camickr

Reputation: 324108

Assuming you have "get" methods for the instance variables you can use a Bean Comparator so you don't have to write custom code.

Upvotes: 0

andersoj
andersoj

Reputation: 22874

Your question has a lot of ambiguity. Here's an example of a 5-field class. This class is sortable using Comparable, which in this case sorts by field a, then field b, and if a and b are identical, the two are equivalent in sort order. If you implement Comparable, you probably also need to implement equals() and ensure that it is consistent, as demanded in the Comparable interface spec. See also javapractices.com "implementing compareTo()" for some good detail.

Working example:

import java.util.Arrays;

class SortableThing implements Comparable<SortableThing>
{
  final String foo;
  final int a, b, c, d, e;

  public SortableThing(String foo, int a, int b, int c, int d, int e)
  {
    this.foo = foo;   this.a = a;
    this.b = b;       this.c = c;
    this.d = d;       this.e = e;
  }

  @Override
  public int compareTo(SortableThing o)
  {
    if (this.a != o.a) 
      return this.a - o.a;
    else if (this.b != o.a)
      return this.b - o.b;
    else return 0;
  }

  @Override
  public boolean equals(Object o)
  {
    if (!(o instanceof SortableThing)) return false;
    SortableThing st = (SortableThing)o;
    return st.a == this.a && st.b == this.b;
  }

  @Override 
  public String toString()
  {
    return new StringBuilder().append(foo).append(": <").append(a)
     .append(',').append(b)
     .append(',').append(c)
     .append(',').append(d)
     .append(',').append(e).append('>').toString();
  }

  public static void main(String[] args)
  {
    final SortableThing one, two, three, four;
    one = new SortableThing("one", 4, 2, 42, 42, 42);
    two = new SortableThing("two", 2, 3, 42, 42, 42);
    three = new SortableThing("three", 2, 2, 42, 42, 42);
    four = new SortableThing("four", 1, 50, 42, 42, 42);
    SortableThing[] list = new SortableThing[] {one,two,three,four};
    System.out.println("Before: "+Arrays.deepToString(list));
    Arrays.sort(list);
    System.out.println("After: "+Arrays.deepToString(list));
  }
}

Output:

Before: [one: <4,2,42,42,42>, two: <2,3,42,42,42>, three: <2,2,42,42,42>, four: <1,50,42,42,42>]
After: [four: <1,50,42,42,42>, three: <2,2,42,42,42>, two: <2,3,42,42,42>, one: <4,2,42,42,42>]

Upvotes: 1

卢声远 Shengyuan Lu
卢声远 Shengyuan Lu

Reputation: 32004

If you mean 'order by a,b,c', I wrote a blog to solve it: 对java.util.List多字段排序. See 2nd snippet of code, sorry it' Chinese, but code and comment are English:)

Upvotes: 0

Adeel Ansari
Adeel Ansari

Reputation: 39887

You can define static Comparators in the class like this,

public static final Comparator<Order> NAME_COMPARATOR = Comparator<Order>(){
                              public int compare(Order o1, Order o2) {
                                  // provide an impl here using order name
                              }
                          }

public static final Comparator<Order> ID_COMPARATOR = Comparator<Order>(){
                              public int compare(Order o1, Order o2) {
                                  // provide an impl here using order id
                              }
                          }

And then pass those while sorting like this,

Collections.sort(list, Order.NAME_COMPARATOR);
Collections.sort(list, Order.ID_COMPARATOR);

Upvotes: 4

Related Questions